26
1
mirror of https://github.com/processone/ejabberd.git synced 2024-12-28 17:38:54 +01:00
xmpp.chapril.org-ejabberd/src/ejabberd_options_doc.erl

1403 lines
67 KiB
Erlang

%%%----------------------------------------------------------------------
%%% ejabberd, Copyright (C) 2002-2021 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
%%% published by the Free Software Foundation; either version 2 of the
%%% License, or (at your option) any later version.
%%%
%%% This program is distributed in the hope that it will be useful,
%%% but WITHOUT ANY WARRANTY; without even the implied warranty of
%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
%%% General Public License for more details.
%%%
%%% You should have received a copy of the GNU General Public License along
%%% with this program; if not, write to the Free Software Foundation, Inc.,
%%% 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
%%%
%%%----------------------------------------------------------------------
-module(ejabberd_options_doc).
%% API
-export([doc/0]).
-include("translate.hrl").
%%%===================================================================
%%% API
%%%===================================================================
doc() ->
[{hosts,
#{value => ?T("[Domain1, Domain2, ...]"),
desc =>
?T("The option defines a list containing one or more "
"domains that 'ejabberd' will serve. This is a "
"**mandatory** option.")}},
{listen,
#{value => "[Options, ...]",
desc =>
?T("The option for listeners configuration. See the "
"http://../listen/[Listen Modules] section "
"for details.")}},
{modules,
#{value => "{Module: Options}",
desc =>
?T("The option for modules configuration. See "
"http://../modules/[Modules] section "
"for details.")}},
{loglevel,
#{value =>
"none | emergency | alert | critical | "
"error | warning | notice | info | debug",
desc =>
?T("Verbosity of log files generated by ejabberd. "
"The default value is 'info'. "
"NOTE: previous versions of ejabberd had log levels "
"defined in numeric format ('0..5'). The numeric values "
"are still accepted for backward compatibility, but "
"are not recommended.")}},
{cache_life_time,
#{value => "timeout()",
desc =>
?T("The time of a cached item to keep in cache. "
"Once it's expired, the corresponding item is "
"erased from cache. The default value is '1 hour'. "
"Several modules have a similar option; and some core "
"ejabberd parts support similar options too, see "
"_`auth_cache_life_time`_, _`oauth_cache_life_time`_, "
"_`router_cache_life_time`_, and _`sm_cache_life_time`_.")}},
{cache_missed,
#{value => "true | false",
desc =>
?T("Whether or not to cache missed lookups. When there is "
"an attempt to lookup for a value in a database and "
"this value is not found and the option is set to 'true', "
"this attempt will be cached and no attempts will be "
"performed until the cache expires (see _`cache_life_time`_). "
"Usually you don't want to change it. Default is 'true'. "
"Several modules have a similar option; and some core "
"ejabberd parts support similar options too, see "
"_`auth_cache_missed`_, _`oauth_cache_missed`_, "
"_`router_cache_missed`_, and _`sm_cache_missed`_.")}},
{cache_size,
#{value => "pos_integer() | infinity",
desc =>
?T("A maximum number of items (not memory!) in cache. "
"The rule of thumb, for all tables except rosters, "
"you should set it to the number of maximum online "
"users you expect. For roster multiply this number "
"by 20 or so. If the cache size reaches this threshold, "
"it's fully cleared, i.e. all items are deleted, and "
"the corresponding warning is logged. You should avoid "
"frequent cache clearance, because this degrades "
"performance. The default value is '1000'. "
"Several modules have a similar option; and some core "
"ejabberd parts support similar options too, see "
"_`auth_cache_size`_, _`oauth_cache_size`_, "
"_`router_cache_size`_, and _`sm_cache_size`_.")}},
{use_cache,
#{value => "true | false",
desc =>
?T("Enable or disable cache. The default is 'true'. "
"Several modules have a similar option; and some core "
"ejabberd parts support similar options too, see "
"_`auth_use_cache`_, _`oauth_use_cache`_, _`router_use_cache`_, "
"and _`sm_use_cache`_.")}},
{default_db,
#{value => "mnesia | sql",
desc =>
?T("Default persistent storage for ejabberd. "
"Modules and other components (e.g. authentication) "
"may have its own value. The default value is 'mnesia'.")}},
{default_ram_db,
#{value => "mnesia | redis | sql",
desc =>
?T("Default volatile (in-memory) storage for ejabberd. "
"Modules and other components (e.g. session management) "
"may have its own value. The default value is 'mnesia'.")}},
{queue_type,
#{value => "ram | file",
desc =>
?T("Default type of queues in ejabberd. "
"Modules may have its own value of the option. "
"The value of 'ram' means that queues will be kept in memory. "
"If value 'file' is set, you may also specify directory "
"in _`queue_dir`_ option where file queues will be placed. "
"The default value is 'ram'.")}},
{version,
#{value => "string()",
desc =>
?T("The option can be used to set custom ejabberd version, "
"that will be used by different parts of ejabberd, for "
"example by _`mod_version`_ module. The default value is "
"obtained at compile time from the underlying version "
"control system.")}},
{acl,
#{value => "{ACLName: {ACLType: ACLValue}}",
desc =>
?T("The option defines access control lists: named sets "
"of rules which are used to match against different targets "
"(such as a JID or an IP address). Every set of rules "
"has name 'ACLName': it can be any string except 'all' or 'none' "
"(those are predefined names for the rules that match all or nothing "
"respectively). The name 'ACLName' can be referenced from other "
"parts of the configuration file, for example in _`access_rules`_ "
"option. The rules of 'ACLName' are represented by mapping "
"'pass:[{ACLType: ACLValue}]'. These can be one of the following:")},
[{user,
#{value => ?T("Username"),
desc =>
?T("If 'Username' is in the form of \"user@server\", "
"the rule matches a JID against this value. "
"Otherwise, if 'Username' is in the form of \"user\", "
"the rule matches any JID that has 'Username' in the node part "
"as long as the server part of this JID is any virtual "
"host served by ejabberd.")}},
{server,
#{value => ?T("Server"),
desc =>
?T("The rule matches any JID from server 'Server'. "
"The value of 'Server' must be a valid "
"hostname or an IP address.")}},
{resource,
#{value => ?T("Resource"),
desc =>
?T("The rule matches any JID with a resource 'Resource'.")}},
{ip,
#{value => ?T("Network"),
desc =>
?T("The rule matches any IP address from the 'Network'.")}},
{user_regexp,
#{value => ?T("Regexp"),
desc =>
?T("If 'Regexp' is in the form of \"regexp@server\", the rule "
"matches any JID with node part matching regular expression "
"\"regexp\" as long as the server part of this JID is equal "
"to \"server\". If 'Regexp' is in the form of \"regexp\", the rule "
"matches any JID with node part matching regular expression "
"\"regexp\" as long as the server part of this JID is any virtual "
"host served by ejabberd.")}},
{server_regexp,
#{value => ?T("Regexp"),
desc =>
?T("The rule matches any JID from the server that "
"matches regular expression 'Regexp'.")}},
{resource_regexp,
#{value => ?T("Regexp"),
desc =>
?T("The rule matches any JID with a resource that "
"matches regular expression 'Regexp'.")}},
{node_regexp,
#{value => ?T("user_regexp@server_regexp"),
desc =>
?T("The rule matches any JID with node part matching regular "
"expression 'user_regexp' and server part matching regular "
"expression 'server_regexp'.")}},
{user_glob,
#{value => ?T("Pattern"),
desc =>
?T("Same as 'user_regexp', but matching is performed on a "
"specified 'Pattern' according to the rules used by the "
"Unix shell.")}},
{server_glob,
#{value => ?T("Pattern"),
desc =>
?T("Same as 'server_regexp', but matching is performed on a "
"specified 'Pattern' according to the rules used by the "
"Unix shell.")}},
{resource_glob,
#{value => ?T("Pattern"),
desc =>
?T("Same as 'resource_regexp', but matching is performed on a "
"specified 'Pattern' according to the rules used by the "
"Unix shell.")}},
{node_glob,
#{value => ?T("Pattern"),
desc =>
?T("Same as 'node_regexp', but matching is performed on a "
"specified 'Pattern' according to the rules used by the "
"Unix shell.")}}]},
{access_rules,
#{value => "{AccessName: {allow|deny: ACLRules|ACLName}}",
desc =>
?T("This option defines "
"http://../basic/#access-rules[Access Rules]. "
"Each access rule is "
"assigned a name that can be referenced from other parts "
"of the configuration file (mostly from 'access' options of "
"ejabberd modules). Each rule definition may contain "
"arbitrary number of 'allow' or 'deny' sections, and each "
"section may contain any number of ACL rules (see _`acl`_ option). "
"There are no access rules defined by default."),
example =>
["access_rules:",
" configure:",
" allow: admin",
" something:",
" deny: someone",
" allow: all",
" s2s_banned:",
" deny: problematic_hosts",
" deny: banned_forever",
" deny:",
" ip: 222.111.222.111/32",
" deny:",
" ip: 111.222.111.222/32",
" allow: all",
" xmlrpc_access:",
" allow:",
" user: peter@example.com",
" allow:",
" user: ivone@example.com",
" allow:",
" user: bot@example.com",
" ip: 10.0.0.0/24"]}},
{acme,
#{value => ?T("Options"),
desc =>
?T("http://../basic/#acme[ACME] configuration, 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. The 'Options' are:"),
example =>
["acme:",
" ca_url: https://acme-v02.api.letsencrypt.org/directory",
" contact:",
" - mailto:admin@domain.tld",
" - mailto:bot@domain.tld",
" auto: true",
" cert_type: rsa"]},
[{ca_url,
#{value => ?T("URL"),
desc =>
?T("The ACME directory URL used as an entry point "
"for the ACME server. The default value is "
"<https://acme-v02.api.letsencrypt.org/directory> - "
"the directory URL of Let's Encrypt authority.")}},
{contact,
#{value => ?T("[Contact, ...]"),
desc =>
?T("A list of contact addresses (typically emails) "
"where an ACME server will send notifications "
"when problems occur. The value of 'Contact' must "
"be in the form of \"scheme:address\" (e.g. "
"\"mailto:user@domain.tld\"). The default "
"is an empty list which means an ACME server "
"will send no notices.")}},
{auto,
#{value => "true | false",
desc =>
?T("Whether to automatically request certificates for "
"all configured domains (that yet have no a certificate) "
"on server start or configuration reload. The default is 'true'.")}},
{cert_type,
#{value => "rsa | ec",
desc =>
?T("A type of a certificate key. Available values are "
"'ec' and 'rsa' for EC and RSA certificates respectively. "
"It's better to have RSA certificates for the purpose "
"of backward compatibility with legacy clients and servers, "
"thus the default is 'rsa'.")}}]},
{allow_contrib_modules,
#{value => "true | false",
desc =>
?T("Whether to allow installation of third-party modules or not. "
"The default value is 'true'.")}},
{allow_multiple_connections,
#{value => "true | false",
desc =>
?T("This option is only used when the anonymous mode is enabled. "
"Setting it to 'true' means that the same username can be "
"taken multiple times in anonymous login mode if different "
"resource are used to connect. This option is only useful "
"in very special occasions. The default value is 'false'.")}},
{anonymous_protocol,
#{value => "login_anon | sasl_anon | both",
desc =>
[?T("Define what anonymous protocol will be used: "), "",
?T("* 'login_anon' means that the anonymous login method will be used. "), "",
?T("* 'sasl_anon' means that the SASL Anonymous method will be used. "), "",
?T("* 'both' means that SASL Anonymous and login anonymous are both "
"enabled."), "",
?T("The default value is 'sasl_anon'."), ""]}},
{api_permissions,
#{value => "[Permission, ...]",
desc =>
?T("Define the permissions for API access. Please consult the "
"ejabberd Docs web -> For Developers -> ejabberd ReST API -> "
"https://docs.ejabberd.im/developer/ejabberd-api/permissions/"
"[API Permissions].")}},
{append_host_config,
#{value => "{Host: Options}",
desc =>
?T("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, 'append_host_config' option can be used.")}},
{auth_cache_life_time,
#{value => "timeout()",
desc =>
?T("Same as _`cache_life_time`_, but applied to authentication cache "
"only. If not set, the value from _`cache_life_time`_ will be used.")}},
{auth_cache_missed,
#{value => "true | false",
desc =>
?T("Same as _`cache_missed`_, but applied to authentication cache "
"only. If not set, the value from _`cache_missed`_ will be used.")}},
{auth_cache_size,
#{value => "pos_integer() | infinity",
desc =>
?T("Same as _`cache_size`_, but applied to authentication cache "
"only. If not set, the value from _`cache_size`_ will be used.")}},
{auth_method,
#{value => "[mnesia | sql | anonymous | external | jwt | ldap | pam, ...]",
desc =>
?T("A list of authentication methods to use. "
"If several methods are defined, authentication is "
"considered successful as long as authentication of "
"at least one of the methods succeeds. "
"The default value is '[mnesia]'.")}},
{auth_opts,
#{value => "[Option, ...]",
desc =>
?T("This is used by the contributed module "
"'ejabberd_auth_http' that can be installed from the "
"https://github.com/processone/ejabberd-contrib[ejabberd-contrib] "
"Git repository. Please refer to that "
"module's README file for details.")}},
{auth_password_format,
#{value => "plain | scram",
note => "improved in 20.01",
desc =>
[?T("The option defines in what format the users passwords "
"are stored:"), "",
?T("* 'plain': The password is stored as plain text "
"in the database. This is risky because the passwords "
"can be read if your database gets compromised. "
"This is the default value. This format allows clients to "
"authenticate using: the old Jabber Non-SASL (XEP-0078), "
"SASL PLAIN, SASL DIGEST-MD5, and SASL SCRAM-SHA-1. "), "",
?T("* 'scram': The password is not stored, only some information "
"that allows to verify the hash provided by the client. "
"It is impossible to obtain the original plain password "
"from the stored information; for this reason, when this "
"value is configured it cannot be changed to plain anymore. "
"This format allows clients to authenticate using: "
"SASL PLAIN and SASL SCRAM-SHA-1."),
?T("The default value is 'plain'.")]}},
{auth_scram_hash,
#{value => "sha | sha256 | sha512",
desc =>
?T("Hash algorithm that should be used to store password in SCRAM format. "
"You shouldn't change this if you already have passwords generated with "
"a different algorithm - users that have such passwords will not be able "
"to authenticate. The default value is 'sha'.")}},
{auth_use_cache,
#{value => "true | false",
desc =>
?T("Same as _`use_cache`_, but applied to authentication cache "
"only. If not set, the value from _`use_cache`_ will be used.")}},
{c2s_cafile,
#{value => ?T("Path"),
desc =>
[?T("Full path to a file containing one or more CA certificates "
"in PEM format. All client certificates should be signed by "
"one of these root CA certificates and should contain the "
"corresponding JID(s) in 'subjectAltName' field. "
"There is no default value."), "",
?T("You can use http://../toplevel/#host-config[host_config] to specify this option per-vhost."), "",
?T("To set a specific file per listener, use the listener's http://../listen-options/#cafile[cafile] option. Please notice that 'c2s_cafile' overrides the listener's 'cafile' option."), ""
]}},
{c2s_ciphers,
#{value => "[Cipher, ...]",
desc =>
?T("A list of OpenSSL ciphers to use for c2s connections. "
"The default value is shown in the example below:"),
example =>
["c2s_ciphers:",
" - HIGH",
" - \"!aNULL\"",
" - \"!eNULL\"",
" - \"!3DES\"",
" - \"@STRENGTH\""]}},
{c2s_dhfile,
#{value => ?T("Path"),
desc =>
?T("Full path to a file containing custom DH parameters "
"to use for c2s connections. "
"Such a file could be created with the command \"openssl "
"dhparam -out dh.pem 2048\". If this option is not specified, "
"2048-bit MODP Group with 256-bit Prime Order Subgroup will be "
"used as defined in RFC5114 Section 2.3.")}},
{c2s_protocol_options,
#{value => "[Option, ...]",
desc =>
?T("List of general SSL options to use for c2s connections. "
"These map to OpenSSL's 'set_options()'. The default value is "
"shown in the example below:"),
example =>
["c2s_protocol_options:",
" - no_sslv3",
" - cipher_server_preference",
" - no_compression"]}},
{c2s_tls_compression,
#{value => "true | false",
desc =>
?T("Whether to enable or disable TLS compression for c2s connections. "
"The default value is 'false'.")}},
{ca_file,
#{value => ?T("Path"),
desc =>
[?T("Path to a file of CA root certificates. "
"The default is to use system defined file if possible."), "",
?T("For server connections, this 'ca_file' option is overridden by the http://../toplevel/#s2s-cafile[s2s_cafile] option."), ""
]}},
{captcha_cmd,
#{value => ?T("Path"),
desc =>
?T("Full path to a script that generates http://../basic/#captcha[CAPTCHA] images. "
"There is no default value: when this option is not "
"set, CAPTCHA functionality is completely disabled.")}},
{captcha_limit,
#{value => "pos_integer() | infinity",
desc =>
?T("Maximum number of http://../basic/#captcha[CAPTCHA] generated images per minute for "
"any given JID. The option is intended to protect the server "
"from CAPTCHA DoS. The default value is 'infinity'.")}},
{captcha_host,
#{value => "String",
desc => ?T("Deprecated. Use _`captcha_url`_ instead.")}},
{captcha_url,
#{value => ?T("URL"),
desc =>
?T("An URL where http://../basic/#captcha[CAPTCHA] requests should be sent. NOTE: you need "
"to configure 'request_handlers' for 'ejabberd_http' listener "
"as well. There is no default value.")}},
{certfiles,
#{value => "[Path, ...]",
desc =>
?T("The option accepts a list of file paths (optionally with "
"wildcards) containing either PEM certificates or PEM private "
"keys. At startup or configuration reload, ejabberd reads all "
"certificates from these files, sorts them, removes duplicates, "
"finds matching private keys and then rebuilds full certificate "
"chains for the use in TLS connections. "
"Use this option when TLS is enabled in either of "
"ejabberd listeners: 'ejabberd_c2s', 'ejabberd_http' and so on. "
"NOTE: if you modify the certificate files or change the value "
"of the option, run 'ejabberdctl reload-config' in order to "
"rebuild and reload the certificate chains."),
example =>
[{?T("If you use https://letsencrypt.org[Let's Encrypt] certificates "
"for your domain \"domain.tld\", the configuration will look "
"like this:"),
["certfiles:",
" - /etc/letsencrypt/live/domain.tld/fullchain.pem",
" - /etc/letsencrypt/live/domain.tld/privkey.pem"]}]}},
{cluster_backend,
#{value => ?T("Backend"),
desc =>
?T("A database backend to use for storing information about "
"cluster. The only available value so far is 'mnesia'.")}},
{cluster_nodes,
#{value => "[Node, ...]",
desc =>
?T("A list of Erlang nodes to connect on ejabberd startup. "
"This option is mostly intended for ejabberd customization "
"and sophisticated setups. The default value is an empty list.")}},
{define_macro,
#{value => "{MacroName: MacroValue}",
desc =>
?T("Defines a macro. The value can be any valid arbitrary "
"YAML value. For convenience, it's recommended to define "
"a 'MacroName' in capital letters. Duplicated macros are not allowed. "
"Macros are processed after additional configuration files have "
"been included, so it is possible to use macros that are defined "
"in configuration files included before the usage. "
"It is possible to use a 'MacroValue' in the definition of another macro."),
example =>
["define_macro:",
" DEBUG: debug",
" LOG_LEVEL: DEBUG",
" USERBOB:",
" user: bob@localhost",
"",
"loglevel: LOG_LEVEL",
"",
"acl:",
" admin: USERBOB"]}},
{disable_sasl_mechanisms,
#{value => "[Mechanism, ...]",
desc =>
?T("Specify a list of SASL mechanisms (such as 'DIGEST-MD5' or "
"'SCRAM-SHA1') that should not be offered to the client. "
"For convenience, the value of 'Mechanism' is case-insensitive. "
"The default value is an empty list, i.e. no mechanisms "
"are disabled by default.")}},
{domain_balancing,
#{value => "{Domain: Options}",
desc =>
?T("An algorithm to load balance the components that are plugged "
"on an ejabberd cluster. It means that you can plug one or several "
"instances of the same component on each ejabberd node and that "
"the traffic will be automatically distributed. The algorithm "
"to deliver messages to the component(s) can be specified by "
"this option. For any component connected as 'Domain', available "
"'Options' are:"),
example =>
["domain_balancing:",
" component.domain.tld:",
" type: destination",
" component_number: 5",
" transport.example.org:",
" type: bare_source"]},
[{type,
#{value => "random | source | destination | bare_source | bare_destination",
desc =>
?T("How to deliver stanzas to connected components: "
"'random' - an instance is chosen at random; "
"'destination' - an instance is chosen by the full JID of "
"the packet's 'to' attribute; "
"'source' - by the full JID of the packet's 'from' attribute; "
"'bare_destination' - by the the bare JID (without resource) "
"of the packet's 'to' attribute; "
"'bare_source' - by the bare JID (without resource) of the "
"packet's 'from' attribute is used. The default value is 'random'.")}},
{component_number,
#{value => "2..1000",
desc =>
?T("The number of components to balance.")}}]},
{extauth_pool_name,
#{value => ?T("Name"),
desc =>
?T("Define the pool name appendix, so the full pool name will be "
"'extauth_pool_Name'. The default value is the hostname.")}},
{extauth_pool_size,
#{value => ?T("Size"),
desc =>
?T("The option defines the number of instances of the same "
"external program to start for better load balancing. "
"The default is the number of available CPU cores.")}},
{extauth_program,
#{value => ?T("Path"),
desc =>
?T("Indicate in this option the full path to the external "
"authentication script. The script must be executable by ejabberd.")}},
{ext_api_headers,
#{value => "Headers",
desc =>
?T("String of headers (separated with commas ',') that will be "
"provided by ejabberd when sending ReST requests. "
"The default value is an empty string of headers: '\"\"'.")}},
{ext_api_http_pool_size,
#{value => "pos_integer()",
desc =>
?T("Define the size of the HTTP pool, that is, the maximum number "
"of sessions that the ejabberd ReST service will handle "
"simultaneously. The default value is: '100'.")}},
{ext_api_path_oauth,
#{value => "Path",
desc =>
?T("Define the base URI path when performing OAUTH ReST requests. "
"The default value is: '\"/oauth\"'.")}},
{ext_api_url,
#{value => "URL",
desc =>
?T("Define the base URI when performing ReST requests. "
"The default value is: '\"http://localhost/api\"'.")}},
{fqdn,
#{value => ?T("Domain"),
desc =>
?T("A fully qualified domain name that will be used in "
"SASL DIGEST-MD5 authentication. The default is detected "
"automatically.")}},
{hide_sensitive_log_data,
#{value => "true | false",
desc =>
?T("A privacy option to not log sensitive data "
"(mostly IP addresses). The default value "
"is 'false' for backward compatibility.")}},
{host_config,
#{value => "{Host: Options}",
desc =>
?T("The option is used to redefine 'Options' for virtual host "
"'Host'. In the example below LDAP authentication method "
"will be used on virtual host 'domain.tld' and SQL method "
"will be used on virtual host 'example.org'."),
example =>
["hosts:",
" - domain.tld",
" - example.org",
"",
"auth_method:",
" - sql",
"",
"host_config:",
" domain.tld:",
" auth_method:",
" - ldap"]}},
{include_config_file,
#{value => "[Filename, ...\\] | {Filename: Options}",
desc =>
?T("Read additional configuration from 'Filename'. If the "
"value is provided in 'pass:[{Filename: Options}]' format, the "
"'Options' must be one of the following:")},
[{disallow,
#{value => "[OptionName, ...]",
desc =>
?T("Disallows the usage of those options in the included "
"file 'Filename'. The options that match this criteria "
"are not accepted. The default value is an empty list.")}},
{allow_only,
#{value => "[OptionName, ...]",
desc =>
?T("Allows only the usage of those options in the included "
"file 'Filename'. The options that do not match this "
"criteria are not accepted. The default value is to include "
"all options.")}}]},
{jwt_auth_only_rule,
#{value => ?T("AccessName"),
desc =>
?T("This ACL rule defines accounts that can use only this auth "
"method, even if others are also defined in the ejabberd "
"configuration file. In other words: if there are several auth "
"methods enabled for this host (JWT, SQL, ...), users that "
"match this rule can only use JWT. "
"The default value is 'none'.")}},
{jwt_jid_field,
#{value => ?T("FieldName"),
desc =>
?T("By default, the JID is defined in the '\"jid\"' JWT field. "
"This option allows to specify other JWT field name "
"where the JID is defined.")}},
{jwt_key,
#{value => ?T("FilePath"),
desc =>
?T("Path to the file that contains the JWK Key. "
"The default value is 'undefined'.")}},
{language,
#{value => ?T("Language"),
desc =>
?T("The option defines the default language of server strings "
"that can be seen by XMPP clients. If an XMPP client does not "
"possess 'xml:lang' attribute, the specified language is used. "
"The default value is '\"en\"'.")}},
{ldap_servers,
#{value => "[Host, ...]",
desc =>
?T("A list of IP addresses or DNS names of your LDAP servers. "
"The default value is '[localhost]'.")}},
{ldap_backups,
#{value => "[Host, ...]",
desc =>
?T("A list of IP addresses or DNS names of LDAP backup servers. "
"When no servers listed in _`ldap_servers`_ option are reachable, "
"ejabberd will try to connect to these backup servers. "
"The default is an empty list, i.e. no backup servers specified. "
"WARNING: ejabberd doesn't try to reconnect back to the main "
"servers when they become operational again, so the only way "
"to restore these connections is to restart ejabberd. This "
"limitation might be fixed in future releases.")}},
{ldap_encrypt,
#{value => "tls | none",
desc =>
?T("Whether to encrypt LDAP connection using TLS or not. "
"The default value is 'none'. NOTE: STARTTLS encryption "
"is not supported.")}},
{ldap_tls_certfile,
#{value => ?T("Path"),
desc =>
?T("A path to a file containing PEM encoded certificate "
"along with PEM encoded private key. This certificate "
"will be provided by ejabberd when TLS enabled for "
"LDAP connections. There is no default value, which means "
"no client certificate will be sent.")}},
{ldap_tls_verify,
#{value => "false | soft | hard",
desc =>
?T("This option specifies whether to verify LDAP server "
"certificate or not when TLS is enabled. When 'hard' is set, "
"ejabberd doesn't proceed if the certificate is invalid. "
"When 'soft' is set, ejabberd proceeds even if the check has failed. "
"The default is 'false', which means no checks are performed.")}},
{ldap_tls_cacertfile,
#{value => ?T("Path"),
desc =>
?T("A path to a file containing PEM encoded CA certificates. "
"This option is required when TLS verification is enabled.")}},
{ldap_tls_depth,
#{value => ?T("Number"),
desc =>
?T("Specifies the maximum verification depth when TLS verification "
"is enabled, i.e. how far in a chain of certificates the "
"verification process can proceed before the verification "
"is considered to be failed. Peer certificate = 0, "
"CA certificate = 1, higher level CA certificate = 2, etc. "
"The value '2' thus means that a chain can at most contain "
"peer cert, CA cert, next CA cert, and an additional CA cert. "
"The default value is '1'.")}},
{ldap_port,
#{value => "1..65535",
desc =>
?T("Port to connect to your LDAP server. The default port is "
"'389' if encryption is disabled and '636' if encryption is "
"enabled.")}},
{ldap_rootdn,
#{value => "RootDN",
desc =>
?T("Bind Distinguished Name. The default value is an empty "
"string, which means \"anonymous connection\".")}},
{ldap_password,
#{value => ?T("Password"),
desc =>
?T("Bind password. The default value is an empty string.")}},
{ldap_deref_aliases,
#{value => "never | always | finding | searching",
desc =>
?T("Whether to dereference aliases or not. "
"The default value is 'never'.")}},
{ldap_base,
#{value => "Base",
desc =>
?T("LDAP base directory which stores users accounts. "
"There is no default value: you must set the option "
"in order for LDAP connections to work properly.")}},
{ldap_uids,
#{value => "[Attr\\] | {Attr: AttrFormat}",
desc =>
?T("LDAP attributes which hold a list of attributes to use "
"as alternatives for getting the JID, where 'Attr' is "
"an LDAP attribute which holds the user's part of the JID and "
"'AttrFormat' must contain one and only one pattern variable "
"\"%u\" which will be replaced by the user's part of the JID. "
"For example, \"%u@example.org\". If the value is in the form "
"of '[Attr]' then 'AttrFormat' is assumed to be \"%u\".")}},
{ldap_filter,
#{value => ?T("Filter"),
desc =>
?T("An LDAP filter as defined in "
"https://tools.ietf.org/html/rfc4515[RFC4515]. "
"There is no default value. Example: "
"\"(&(objectClass=shadowAccount)(memberOf=XMPP Users))\". "
"NOTE: don't forget to close brackets and don't use superfluous "
"whitespaces. Also you must not use \"uid\" attribute in the "
"filter because this attribute will be appended to the filter "
"automatically.")}},
{ldap_dn_filter,
#{value => "{Filter: FilterAttrs}",
desc =>
?T("This filter is applied on the results returned by the main "
"filter. The filter performs an additional LDAP lookup to make "
"the complete result. This is useful when you are unable to "
"define all filter rules in 'ldap_filter'. You can define "
"\"%u\", \"%d\", \"%s\" and \"%D\" pattern variables in 'Filter': "
"\"%u\" is replaced by a user's part of the JID, \"%d\" is "
"replaced by the corresponding domain (virtual host), all \"%s\" "
"variables are consecutively replaced by values from the attributes "
"in 'FilterAttrs' and \"%D\" is replaced by Distinguished Name from "
"the result set. There is no default value, which means the "
"result is not filtered. WARNING: Since this filter makes "
"additional LDAP lookups, use it only as the last resort: "
"try to define all filter rules in _`ldap_filter`_ option if possible."),
example =>
["ldap_dn_filter:",
" \"(&(name=%s)(owner=%D)(user=%u@%d))\": [sn]"]}},
{log_rotate_count,
#{value => ?T("Number"),
desc =>
?T("The number of rotated log files to keep. "
"The default value is '1', which means that only keeps "
"`ejabberd.log.0`, `error.log.0` and `crash.log.0`.")}},
{log_rotate_size,
#{value => "pos_integer() | infinity",
desc =>
?T("The size (in bytes) of a log file to trigger rotation. "
"If set to 'infinity', log rotation is disabled. "
"The default value is '10485760' (that is, 10 Mb).")}},
{max_fsm_queue,
#{value => ?T("Size"),
desc =>
?T("This option specifies the maximum number of elements "
"in the queue of the FSM (Finite State Machine). Roughly "
"speaking, each message in such queues represents one "
"XML stanza queued to be sent into its relevant outgoing "
"stream. If queue size reaches the limit (because, for "
"example, the receiver of stanzas is too slow), the FSM "
"and the corresponding connection (if any) will be terminated "
"and error message will be logged. The reasonable value for "
"this option depends on your hardware configuration. "
"The allowed values are positive integers. "
"The default value is '10000'.")}},
{negotiation_timeout,
#{value => "timeout()",
desc =>
?T("Time to wait for an XMPP stream negotiation to complete. "
"When timeout occurs, the corresponding XMPP stream is closed. "
"The default value is '30' seconds.")}},
{net_ticktime,
#{value => "timeout()",
desc =>
?T("This option can be used to tune tick time parameter of "
"'net_kernel'. It tells Erlang VM how often nodes should check "
"if intra-node communication was not interrupted. This option "
"must have identical value on all nodes, or it will lead to subtle "
"bugs. Usually leaving default value of this is option is best, "
"tweak it only if you know what you are doing. "
"The default value is '1 minute'.")}},
{new_sql_schema,
#{value => "true | false",
desc =>
{?T("Whether to use 'new' SQL schema. All schemas are located "
"at <https://github.com/processone/ejabberd/tree/~s/sql>. "
"There are two schemas available. The default legacy schema "
"allows to store one XMPP domain into one ejabberd database. "
"The 'new' schema allows to handle several XMPP domains in a "
"single ejabberd database. Using this 'new' schema is best when "
"serving several XMPP domains and/or changing domains from "
"time to time. This avoid need to manage several databases and "
"handle complex configuration changes. The default depends on "
"configuration flag '--enable-new-sql-schema' which is set "
"at compile time."),
[binary:part(ejabberd_config:version(), {0,5})]}}},
{oauth_access,
#{value => ?T("AccessName"),
desc => ?T("By default creating OAuth tokens is not allowed. "
"To define which users can create OAuth tokens, "
"you can refer to an ejabberd access rule in the "
"'oauth_access' option. Use 'all' to allow everyone "
"to create tokens.")}},
{oauth_cache_life_time,
#{value => "timeout()",
desc =>
?T("Same as _`cache_life_time`_, but applied to OAuth cache "
"only. If not set, the value from _`cache_life_time`_ will be used.")}},
{oauth_cache_missed,
#{value => "true | false",
desc =>
?T("Same as _`cache_missed`_, but applied to OAuth cache "
"only. If not set, the value from _`cache_missed`_ will be used.")}},
{oauth_cache_rest_failure_life_time,
#{value => "timeout()",
note => "added in 21.01",
desc =>
?T("The time that a failure in OAuth ReST is cached. "
"The default value is 'infinity'.")}},
{oauth_cache_size,
#{value => "pos_integer() | infinity",
desc =>
?T("Same as _`cache_size`_, but applied to OAuth cache "
"only. If not set, the value from _`cache_size`_ will be used.")}},
{oauth_client_id_check,
#{value => "allow | db | deny",
desc =>
?T("Define whether the client authentication is always allowed, "
"denied, or it will depend if the client ID is present in the "
"database. The default value is 'allow'.")}},
{oauth_use_cache,
#{value => "true | false",
desc =>
?T("Same as _`use_cache`_, but applied to OAuth cache "
"only. If not set, the value from _`use_cache`_ will be used.")}},
{oauth_db_type,
#{value => "mnesia | sql",
desc =>
?T("Database backend to use for OAuth authentication. "
"The default value is picked from _`default_db`_ option, or "
"if it's not set, 'mnesia' will be used.")}},
{oauth_expire,
#{value => "timeout()",
desc =>
?T("Time during which the OAuth token is valid, in seconds. "
"After that amount of time, the token expires and the delegated "
"credential cannot be used and is removed from the database. "
"The default is '4294967' seconds.")}},
{oom_killer,
#{value => "true | false",
desc =>
?T("Enable or disable OOM (out-of-memory) killer. "
"When system memory raises above the limit defined in "
"_`oom_watermark`_ option, ejabberd triggers OOM killer "
"to terminate most memory consuming Erlang processes. "
"Note that in order to maintain functionality, ejabberd only "
"attempts to kill transient processes, such as those managing "
"client sessions, s2s or database connections. "
"The default value is 'true'.")}},
{oom_queue,
#{value => ?T("Size"),
desc =>
?T("Trigger OOM killer when some of the running Erlang processes "
"have messages queue above this 'Size'. Note that "
"such processes won't be killed if _`oom_killer`_ option is set "
"to 'false' or if 'oom_watermark' is not reached yet.")}},
{oom_watermark,
#{value => ?T("Percent"),
desc =>
?T("A percent of total system memory consumed at which "
"OOM killer should be activated with some of the processes "
"possibly be killed (see _`oom_killer`_ option). Later, when "
"memory drops below this 'Percent', OOM killer is deactivated. "
"The default value is '80' percents.")}},
{outgoing_s2s_families,
#{value => "[ipv4 | ipv6, ...]",
desc =>
?T("Specify which address families to try, in what order. "
"The default is '[ipv4, ipv6]' which means it first tries "
"connecting with IPv4, if that fails it tries using IPv6.")}},
{outgoing_s2s_ipv4_address,
#{value => "Address",
note => "added in 20.12",
desc =>
?T("Specify the IPv4 address that will be used when establishing "
"an outgoing S2S IPv4 connection, for example \"127.0.0.1\". "
"The default value is 'undefined'.")}},
{outgoing_s2s_ipv6_address,
#{value => "Address",
note => "added in 20.12",
desc =>
?T("Specify the IPv6 address that will be used when establishing "
"an outgoing S2S IPv6 connection, for example "
"\"::FFFF:127.0.0.1\". The default value is 'undefined'.")}},
{outgoing_s2s_port,
#{value => "1..65535",
desc =>
?T("A port number to use for outgoing s2s connections when the target "
"server doesn't have an SRV record. The default value is '5269'.")}},
{outgoing_s2s_timeout,
#{value => "timeout()",
desc =>
?T("The timeout in seconds for outgoing S2S connection attempts. "
"The default value is '10' seconds.")}},
{pam_service,
#{value => ?T("Name"),
desc =>
?T("This option defines the PAM service name. Refer to the PAM "
"documentation of your operation system for more information. "
"The default value is 'ejabberd'.")}},
{pam_userinfotype,
#{value => "username | jid",
desc =>
?T("This option defines what type of information about the "
"user ejabberd provides to the PAM service: only the username, "
"or the user's JID. Default is 'username'.")}},
{pgsql_users_number_estimate,
#{value => "true | false",
desc =>
?T("Whether to use PostgreSQL estimation when counting registered "
"users. The default value is 'false'.")}},
{queue_dir,
#{value => ?T("Directory"),
desc =>
?T("If _`queue_type`_ option is set to 'file', use this 'Directory' "
"to store file queues. The default is to keep queues inside "
"Mnesia directory.")}},
{redis_connect_timeout,
#{value => "timeout()",
desc =>
?T("A timeout to wait for the connection to be re-established "
"to the Redis server. The default is '1 second'.")}},
{redis_db,
#{value => ?T("Number"),
desc => ?T("Redis database number. The default is '0'.")}},
{redis_password,
#{value => ?T("Password"),
desc =>
?T("The password to the Redis server. "
"The default is an empty string, i.e. no password.")}},
{redis_pool_size,
#{value => ?T("Number"),
desc =>
?T("The number of simultaneous connections to the Redis server. "
"The default value is '10'.")}},
{redis_port,
#{value => "1..65535",
desc =>
?T("The port where the Redis server is accepting connections. "
"The default is '6379'.")}},
{redis_queue_type,
#{value => "ram | file",
desc =>
?T("The type of request queue for the Redis server. "
"See description of _`queue_type`_ option for the explanation. "
"The default value is the value defined in _`queue_type`_ "
"or 'ram' if the latter is not set.")}},
{redis_server,
#{value => ?T("Hostname"),
desc =>
?T("A hostname or an IP address of the Redis server. "
"The default is 'localhost'.")}},
{registration_timeout,
#{value => "timeout()",
desc =>
?T("This is a global option for module _`mod_register`_. "
"It limits the frequency of registrations from a given "
"IP or username. So, a user that tries to register a "
"new account from the same IP address or JID during "
"this time after their previous registration "
"will receive an error with the corresponding explanation. "
"To disable this limitation, set the value to 'infinity'. "
"The default value is '600 seconds'.")}},
{resource_conflict,
#{value => "setresource | closeold | closenew",
desc =>
?T("NOTE: this option is deprecated and may be removed "
"anytime in the future versions. The possible values "
"match exactly the three possibilities described in "
"https://tools.ietf.org/html/rfc6120#section-7.7.2.2"
"[XMPP Core: section 7.7.2.2]. "
"The default value is 'closeold'. If the client "
"uses old Jabber Non-SASL authentication (XEP-0078), "
"then this option is not respected, and the action performed "
"is 'closeold'.")}},
{router_cache_life_time,
#{value => "timeout()",
desc =>
?T("Same as _`cache_life_time`_, but applied to routing table cache "
"only. If not set, the value from _`cache_life_time`_ will be used.")}},
{router_cache_missed,
#{value => "true | false",
desc =>
?T("Same as _`cache_missed`_, but applied to routing table cache "
"only. If not set, the value from _`cache_missed`_ will be used.")}},
{router_cache_size,
#{value => "pos_integer() | infinity",
desc =>
?T("Same as _`cache_size`_, but applied to routing table cache "
"only. If not set, the value from _`cache_size`_ will be used.")}},
{router_db_type,
#{value => "mnesia | redis | sql",
desc =>
?T("Database backend to use for routing information. "
"The default value is picked from _`default_ram_db`_ option, or "
"if it's not set, 'mnesia' will be used.")}},
{router_use_cache,
#{value => "true | false",
desc =>
?T("Same as _`use_cache`_, but applied to routing table cache "
"only. If not set, the value from _`use_cache`_ will be used.")}},
{rpc_timeout,
#{value => "timeout()",
desc =>
?T("A timeout for remote function calls between nodes "
"in an ejabberd cluster. You should probably never change "
"this value since those calls are used for internal needs "
"only. The default value is '5' seconds.")}},
{s2s_access,
#{value => ?T("Access"),
desc =>
?T("This http://../basic/#access-rules[Access Rule] defines to "
"what remote servers can s2s connections be established. "
"The default value is 'all'; no restrictions are applied, it is"
" allowed to connect s2s to/from all remote servers.")}},
{s2s_cafile,
#{value => ?T("Path"),
desc =>
[?T("A path to a file with CA root certificates that will "
"be used to authenticate s2s connections. If not set, "
"the value of http://../toplevel/#ca-file[ca_file] will be used."), "",
?T("You can use http://../toplevel/#host-config[host_config] to specify this option per-vhost."), ""
]}},
{s2s_ciphers,
#{value => "[Cipher, ...]",
desc =>
?T("A list of OpenSSL ciphers to use for s2s connections. "
"The default value is shown in the example below:"),
example =>
["s2s_ciphers:",
" - HIGH",
" - \"!aNULL\"",
" - \"!eNULL\"",
" - \"!3DES\"",
" - \"@STRENGTH\""]}},
{s2s_dhfile,
#{value => ?T("Path"),
desc =>
?T("Full path to a file containing custom DH parameters "
"to use for s2s connections. "
"Such a file could be created with the command \"openssl "
"dhparam -out dh.pem 2048\". If this option is not specified, "
"2048-bit MODP Group with 256-bit Prime Order Subgroup will be "
"used as defined in RFC5114 Section 2.3.")}},
{s2s_protocol_options,
#{value => "[Option, ...]",
desc =>
?T("List of general SSL options to use for s2s connections. "
"These map to OpenSSL's 'set_options()'. The default value is "
"shown in the example below:"),
example =>
["s2s_protocol_options:",
" - no_sslv3",
" - cipher_server_preference",
" - no_compression"]}},
{s2s_tls_compression,
#{value => "true | false",
desc =>
?T("Whether to enable or disable TLS compression for s2s connections. "
"The default value is 'false'.")}},
{s2s_dns_retries,
#{value => ?T("Number"),
desc =>
?T("DNS resolving retries. The default value is '2'.")}},
{s2s_dns_timeout,
#{value => "timeout()",
desc =>
?T("The timeout for DNS resolving. The default value is '10' seconds.")}},
{s2s_max_retry_delay,
#{value => "timeout()",
desc =>
?T("The maximum allowed delay for s2s connection retry to connect after a "
"failed connection attempt. The default value is '300' seconds "
"(5 minutes).")}},
{s2s_queue_type,
#{value => "ram | file",
desc =>
?T("The type of a queue for s2s packets. "
"See description of _`queue_type`_ option for the explanation. "
"The default value is the value defined in _`queue_type`_ "
"or 'ram' if the latter is not set.")}},
{s2s_timeout,
#{value => "timeout()",
desc =>
?T("A time to wait before closing an idle s2s connection. "
"The default value is '10 minutes'.")}},
{s2s_use_starttls,
#{value => "true | false | optional | required",
desc =>
?T("Whether to use STARTTLS for s2s connections. "
"The value of 'false' means STARTTLS is prohibited. "
"The value of 'true' or 'optional' means STARTTLS is enabled "
"but plain connections are still allowed. And the value of "
"'required' means that only STARTTLS connections are allowed. "
"The default value is 'false' (for historical reasons).")}},
{s2s_zlib,
#{value => "true | false",
desc =>
?T("Whether to use 'zlib' compression (as defined in "
"https://xmpp.org/extensions/xep-0138.html[XEP-0138]) or not. "
"The default value is 'false'. WARNING: this type "
"of compression is nowadays considered insecure.")}},
{shaper,
#{value => "{ShaperName: Rate}",
desc =>
?T("The option defines a set of shapers. Every shaper is assigned "
"a name 'ShaperName' that can be used in other parts of the "
"configuration file, such as _`shaper_rules`_ option. The shaper "
"itself is defined by its '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. In the example below shaper 'normal' limits "
"the traffic speed to 1,000 bytes/sec and shaper 'fast' limits "
"the traffic speed to 50,000 bytes/sec:"),
example =>
["shaper:",
" normal: 1000",
" fast: 50000"]}},
{shaper_rules,
#{value => "{ShaperRuleName: {Number|ShaperName: ACLRule|ACLName}}",
desc =>
?T("An entry allowing to declaring shaper to use for matching user/hosts. "
"Semantics is similar to _`access_rules`_ option, the only difference is "
"that instead using 'allow' or 'deny', a name of a shaper (defined in "
"_`shaper`_ option) or a positive number should be used."),
example =>
["shaper_rules:",
" connections_limit:",
" 10:",
" user: peter@example.com",
" 100: admin",
" 5: all",
" download_speed:",
" fast: admin",
" slow: anonymous_users",
" normal: all",
" log_days: 30"]}},
{sm_cache_life_time,
#{value => "timeout()",
desc =>
?T("Same as _`cache_life_time`_, but applied to client sessions table cache "
"only. If not set, the value from _`cache_life_time`_ will be used.")}},
{sm_cache_missed,
#{value => "true | false",
desc =>
?T("Same as _`cache_missed`_, but applied to client sessions table cache "
"only. If not set, the value from _`cache_missed`_ will be used.")}},
{sm_cache_size,
#{value => "pos_integer() | infinity",
desc =>
?T("Same as _`cache_size`_, but applied to client sessions table cache "
"only. If not set, the value from _`cache_size`_ will be used.")}},
{sm_db_type,
#{value => "mnesia | redis | sql",
desc =>
?T("Database backend to use for client sessions information. "
"The default value is picked from _`default_ram_db`_ option, or "
"if it's not set, 'mnesia' will be used.")}},
{sm_use_cache,
#{value => "true | false",
desc =>
?T("Same as _`use_cache`_, but applied to client sessions table cache "
"only. If not set, the value from _`use_cache`_ will be used.")}},
{sql_type,
#{value => "mssql | mysql | odbc | pgsql | sqlite",
desc =>
?T("The type of an SQL connection. The default is 'odbc'.")}},
{sql_connect_timeout,
#{value => "timeout()",
desc =>
?T("A time to wait for connection to an SQL server to be "
"established. The default value is '5' seconds.")}},
{sql_database,
#{value => ?T("Database"),
desc =>
?T("An SQL database name. For SQLite this must be a full "
"path to a database file. The default value is 'ejabberd'.")}},
{sql_keepalive_interval,
#{value => "timeout()",
desc =>
?T("An interval to make a dummy SQL request to keep alive the "
"connections to the database. There is no default value, so no "
"keepalive requests are made.")}},
{sql_odbc_driver,
#{value => "Path",
note => "added in 20.12",
desc =>
?T("Path to the ODBC driver to use to connect to a Microsoft SQL "
"Server database. This option is only valid if the _`sql_type`_ "
"option is set to 'mssql'. "
"The default value is: 'libtdsodbc.so'")}},
{sql_password,
#{value => ?T("Password"),
desc =>
?T("The password for SQL authentication. The default is empty string.")}},
{sql_pool_size,
#{value => ?T("Size"),
desc =>
?T("Number of connections to the SQL server that ejabberd will "
"open for each virtual host. The default value is 10. WARNING: "
"for SQLite this value is '1' by default and it's not recommended "
"to change it due to potential race conditions.")}},
{sql_port,
#{value => "1..65535",
desc =>
?T("The port where the SQL server is accepting connections. "
"The default is '3306' for MySQL, '5432' for PostgreSQL and "
"'1433' for MS SQL. The option has no effect for SQLite.")}},
{sql_prepared_statements,
#{value => "true | false",
note => "added in 20.01",
desc =>
?T("This option is 'true' by default, and is useful to disable "
"prepared statements. The option is valid for PostgreSQL.")}},
{sql_query_timeout,
#{value => "timeout()",
desc =>
?T("A time to wait for an SQL query response. "
"The default value is '60' seconds.")}},
{sql_queue_type,
#{value => "ram | file",
desc =>
?T("The type of a request queue for the SQL server. "
"See description of _`queue_type`_ option for the explanation. "
"The default value is the value defined in _`queue_type`_ "
"or 'ram' if the latter is not set.")}},
{sql_server,
#{value => ?T("Host"),
desc =>
?T("A hostname or an IP address of the SQL server. "
"The default value is 'localhost'.")}},
{sql_ssl,
#{value => "true | false",
note => "improved in 20.03",
desc =>
?T("Whether to use SSL encrypted connections to the "
"SQL server. The option is only available for MySQL and "
"PostgreSQL. The default value is 'false'.")}},
{sql_ssl_cafile,
#{value => ?T("Path"),
desc =>
?T("A path to a file with CA root certificates that will "
"be used to verify SQL connections. Implies _`sql_ssl`_ "
"and _`sql_ssl_verify`_ options are set to 'true'. "
"There is no default which means "
"certificate verification is disabled.")}},
{sql_ssl_certfile,
#{value => ?T("Path"),
desc =>
?T("A path to a certificate file that will be used "
"for SSL connections to the SQL server. Implies _`sql_ssl`_ "
"option is set to 'true'. There is no default which means "
"ejabberd won't provide a client certificate to the SQL "
"server.")}},
{sql_ssl_verify,
#{value => "true | false",
desc =>
?T("Whether to verify SSL connection to the SQL server against "
"CA root certificates defined in _`sql_ssl_cafile`_ option. "
"Implies _`sql_ssl`_ option is set to 'true'. "
"The default value is 'false'.")}},
{sql_start_interval,
#{value => "timeout()",
desc =>
?T("A time to wait before retrying to restore failed SQL connection. "
"The default value is '30' seconds.")}},
{sql_username,
#{value => ?T("Username"),
desc =>
?T("A user name for SQL authentication. "
"The default value is 'ejabberd'.")}},
{trusted_proxies,
#{value => "all | [Network1, Network2, ...]",
desc =>
?T("Specify what proxies are trusted when an HTTP request "
"contains the header 'X-Forwarded-For'. You can specify "
"'all' to allow all proxies, or specify a list of IPs, "
"possibly with masks. The default value is an empty list. "
"This allows, if enabled, to be able to know the real IP "
"of the request, for admin purpose, or security configuration "
"(for example using 'mod_fail2ban'). IMPORTANT: The proxy MUST "
"be configured to set the 'X-Forwarded-For' header if you "
"enable this option as, otherwise, the client can set it "
"itself and as a result the IP value cannot be trusted for "
"security rules in ejabberd.")}},
{validate_stream,
#{value => "true | false",
desc =>
?T("Whether to validate any incoming XML packet according "
"to the schemas of "
"https://github.com/processone/xmpp#supported-xmpp-elements"
"[supported XMPP extensions]. WARNING: the validation is only "
"intended for the use by client developers - don't enable "
"it in production environment. The default value is 'false'.")}},
{websocket_origin,
#{value => "ignore | URL",
desc =>
?T("This option enables validation for 'Origin' header to "
"protect against connections from other domains than given "
"in the configuration file. In this way, the lower layer load "
"balancer can be chosen for a specific ejabberd implementation "
"while still providing a secure Websocket connection. "
"The default value is 'ignore'. An example value of the 'URL' is "
"\"https://test.example.org:8081\".")}},
{websocket_ping_interval,
#{value => "timeout()",
desc =>
?T("Defines time between pings sent by the server to a client "
"(Websocket level protocol pings are used for this) to keep "
"a connection active. If the client doesn't respond to two "
"consecutive pings, the connection will be assumed as closed. "
"The value of '0' can be used to disable the feature. This option "
"makes the server sending pings only for connections using the RFC "
"compliant protocol. For older style connections the server "
"expects that whitespace pings would be used for this purpose. "
"The default value is '60' seconds.")}},
{websocket_timeout,
#{value => "timeout()",
desc =>
?T("Amount of time without any communication after which the "
"connection would be closed. The default value is '300' seconds.")}}].
%%%===================================================================
%%% Internal functions
%%%===================================================================