⬆️ ⬇️

CentOS 5.x, 6.x and EJabberd v2.x + Win2008AD

I have long wanted to do it and at the end it was fully implemented, a bunch of EJabberd with accounts from Active Directory Win 2008 . With the formation of the structure of the roster and the formation of the displayed user aliases based on the properties of user accounts that were created in AD . Since before re-reading a bunch of material, everywhere in pieces and not working.





To install ejabberd from the package, you need to connect the EPEL repository, run:



For CentOS 5 :

')

rpm -Uvh dl.fedoraproject.org/pub/epel/5/i386/epel-release-5-4.noarch.rpm



For CentOS 6:



rpm -Uvh dl.fedoraproject.org/pub/epel/6/i386/epel-release-6-7.noarch.rpm



or



rpm -Uvh dl.fedoraproject.org/pub/epel/6/x86_64/epel-release-6-8.noarch.rpm



Now install the ejabberd package:



yum install ejabberd



Open for editing the config /etc/ejabberd/ejabberd.cfg



We assign the rights to remote control to the user admin . Find a section:



%%

%% Remove the Access Control Lists before new ones are added.

%%

%% override_acls.





And add the line:



{acl, admin, {user, "admin", "server.int"}}.



Find the SERVED HOSTNAMES section and edit the domain name in the line:



{hosts, ["server.int"]}.



Let's try to start the ejabberd service:



service ejabberd start



If the service starts normally, you need to add the first user who can manage all the settings of the service, we run



ejabberdctl register admin server.int 123456



Now we go to the browser:



We type server.int : 5280 / admin / and enter the user admin@server.int and the password 123456 . The admin control panel of the ejabberd service will appear.



Add service to autorun:



chkconfig ejabberd on



The first and simple stage is done, ejabberd works, but users in this configuration need to be added by hand and they will be stored in the local ejabberd database. But since it was decided to link EJabberd and Win2008AD accounts, we continue the configuration.



Open for editing the config /etc/ejabberd/ejabberd.cfg



Find the line we created to enter the admin web panel:



{acl, admin, {user, "admin", "server.int"}}.



After it we add a new line:



{acl, admin, {user, "userjabber", "server.int"}}.



This user userjabber must first be created in AD in order to have access to the admin web panel.



Attention, after connecting to AD, the local user admin , who had access to the admin web panel, will expire and only the user userjabber will be able to enter the admin panel.



Next, configure the connection to AD .



Find the line and bring it to the form (disable the internal authorization):



%% {auth_method, internal}.



Find the string and bring it to the form (we connect the LDAP authorization, AD ):



{auth_method, ldap}.



Find the block:



%%

%% Authentication using LDAP

%%



Add settings for connecting to the AD server:



{ldap_servers, ["192.168.151.2"]}.

{ldap_port, 389}.



{ldap_uids, [{"sAMAccountName", "% u"}]}.

{ldap_filter, "(objectCategory = person)"}.



{ldap_base, "DC = developer, DC = com"}.

{ldap_rootdn, "userjabber@developer.com"}.

{ldap_password, "123456"}.





Now you need to connect the modules to form the structure of the roster and the formation of the displayed aliases of users based on the properties of user accounts that were created in AD . For example, we created in AD users ivanov.i, petrov.p . In the user's properties, on the Home tab, the user ivanov.i has the entries Last Name: Ivanov , First Name: Ivan , and on the Organization tab , in the Department: Developers field. The user petrov.p , also has an entry in the field Department: Developers .



So that now in the jabber client there was beauty and order we connect the modules

mod_shared_roster_ldap and mod_vcard_ldap .



Find the string and reduce it to the form:



%% {mod_shared_roster, []},



Add the formation of a roster (Formation of a list of users by groups, displayed by connected clients. Belonging to a group is read from the user properties created in AD 2008 , the Organization tab, the Department field.):



{mod_shared_roster_ldap,

[{ldap_groupattr, "department"},

{ldap_groupdesc, "department"},

{ldap_rfilter, "(objectCategory = person)"},

{ldap_memberattr, "sAMAccountName"},

{ldap_userdesc, "cn"}

]

},



Find the string and reduce it to the form:



%% {mod_vcard, []},



Add the formation of user aliases (Reading the VCard fields of each user from AD 2008 , ie the fields that are contained in the user properties. Names, last names, etc.):



{mod_vcard_ldap,

[{ldap_vcard_map,

[{"NICKNAME", "% s", ["displayname"]},

{"GIVEN", "% s", ["givenName"]},

{"MIDDLE", "% s", ["initials"]},

{"FAMILY", "% s", ["sn"]},

{"FN", "% s", ["displayName"]},

{"EMAIL", "% s", ["mail"]},

{"ORGNAME", "% s", ["company"]},

{"ORGUNIT", "% s", ["department"]},

{"CTRY", "% s", ["c"]},

{"LOCALITY", "% s", ["l"]},

{"STREET", "% s", ["streetAddress"]},

{"REGION", "% s", ["st"]},

{"PCODE", "% s", ["postalCode"]},

{"TITLE", "% s", ["title"]},

{"URL", "% s", ["wWWHomePage"]},

{"DESC", "% s", ["description"]},

{"TEL", "% s", ["telephoneNumber"]}]},

{ldap_search_fields,

[{"User", "% u"},

{"Name", "givenName"},

{"Family Name", "sn"},

{"Email", "mail"},

{"Company", "company"},

{"Department", "department"},

{"Role", "title"},

{"Description", "description"},

{"Phone", "telephoneNumber"}]},

{ldap_search_reported,

[{"Full Name", "FN"},

{"Nickname", "NICKNAME"},

{"Email", "EMAIL"}]}

]

},



Restart service:



service ejabberd restart



If passed without errors, try connecting the jabber client with our server.



Errors and all other records about the work of the service can be viewed in the logs in the / var / log / ejabberd directory.



After connecting to the client jabber, we have the Developers folder and there are two users in it, Ivanov Ivan and Petrov Peter .



I bring 100% working config:



Working config
%%%

%%% ejabberd configuration file

%%%

%%% '



%%% The parameters used in this configuration file

%%% in the ejabberd Installation and Operation Guide.

%%% Please consult, it is included with

%%% your copy of ejabberd, and is also available online at

%%% www.process-one.net/en/ejabberd/docs



%%% This configuration file contains Erlang terms.

%%% In the syntax, here are the concepts:

%%%

%%% - The character to comment is a line is%

%%%

%%% - Each term ends in a dot, for example:

%%% override_global.

%%%

%%% - A tuple has a fixed definition, its elements are

%%% enclosed in {}, and separated with commas:

%%% {loglevel, 4}.

%%%

%%% - A list of you want,

%%% and is enclosed in [], for example:

%%% [http_poll, web_admin, tls]

%%%

%%% - A keyword of ejabberd is a word in lowercase.

%%% Strings are enclosed in "" and can contain spaces, dots, ...

%%% {language, "en"}.

%%% {ldap_rootdn, "dc = example, dc = com"}.

%%%

%%% - This term includes a tuple, a keyword, a list, and two strings:

%%% {hosts, ["jabber.example.net", "im.example.com"]}.

%%%



%%%. =======================

%%% 'OVERRIDE STORED OPTIONS



%%

%% Override the values ​​stored in the database.

%%



%%

%% Override global options (shared by all ejabberd nodes in a cluster).

%%

%% override_global.



%%

%% Override local options (specific for this particular ejabberd node).

%%

%% override_local.



%%

%% Remove the Control Lists before new ones are added.

%%

%% override_acls.



{acl, admin, {user, "userjabber", "server.int"}}.



%%%. =========

%%% 'DEBUGGING



%%

%% 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}.



%%

%% watchdog_admins: Only for developers: if an ejabberd process

%% consumes a lot of memory send live notifications to these XMPP

%% accounts.

%%

%% {watchdog_admins, [“bob@example.com”]}.



%%%. ================

%%% 'SERVED HOSTNAMES



%%

%% hosts: Domains served by ejabberd.

%% You can define one or several, for example:

%% {hosts, ["example.net", "example.com", "example.org"]}.

%%

{hosts, ["server.int"]}.



%%

%% route_subdomains: Delegate subdomains to other XMPP servers.

%% For example, if this ejabberd serves example.org and you want

%% to allow communication with an XMPP server called im.example.org.

%%

%% {route_subdomains, s2s}.



%%%. ===============

%%% 'LISTENING PORTS



%%

%% listen: The ports ejabberd will listen on, which service is is handled

%% by and what options to start it with.

%%

{listen,

[



{5222, ejabberd_c2s, [



%%

%% If TLS is compiled in you installed a SSL

%% certificate, specify the full path to the

%% file and uncomment this line:

%%

{certfile, "/etc/ejabberd/ejabberd.pem"}, starttls,



{access, c2s},

{shaper, c2s_shaper},

{max_stanza_size, 65536}

]},



%%

%% To enable the old SSL connection method 5223:

%%

%% {5223, ejabberd_c2s, [

%% {access, c2s},

%% {shaper, c2s_shaper},

%% {certfile, "/etc/ejabberd/ejabberd.pem"}, tls,

%% {max_stanza_size, 65536}

%%]},



{5269, ejabberd_s2s_in, [

{shaper, s2s_shaper},

{max_stanza_size, 131072}

]},



%%

%% ejabberd_service: Interact with external components (transports, ...)

%%

%% {8888, ejabberd_service, [

%% {access, all},

%% {shaper_rule, fast},

%% {ip, {127, 0, 0, 1}},

%% {hosts, ["icq.example.org", "sms.example.org"],

%% [{password, "secret"}]

%%}

%%]},



%%

%% ejabberd_stun: Handles STUN Binding requests

%%

%% {{3478, udp}, ejabberd_stun, []},



{5280, ejabberd_http, [

%% {request_handlers,

%% [

%% {["pub", "archive"], mod_http_fileserver}

%%]},

captcha

http_bind,

http_poll

%% register

web_admin

]}



]}.



%%

%% s2s_use_starttls: Enable STARTTLS + Dialback for S2S connections.

%% Allowed values ​​are: false optional required required_trusted

%% You must specify a certificate file.

%%

%% {s2s_use_starttls, optional}.



%%

%% s2s_certfile: Specify a certificate file.

%%

%% {s2s_certfile, "/etc/ejabberd/ejabberd.pem"}.



%%

%% domain_certfile: Specify a certificate for each served hostname.

%%

%% {domain_certfile, "example.org", "/path/to/example_org.pem"}.

%% {domain_certfile, "example.com", "/path/to/example_com.pem"}.



%%

%% S2S whitelist or blacklist

%%

%% Default s2s policy for undefined hosts.

%%

%% {s2s_default_policy, allow}.



%%

%% Allow or deny communication with specific servers.

%%

%% {{s2s_host, "goodhost.org"}, allow}.

%% {{s2s_host, "badhost.org"}, deny}.



%%

%% Outgoing S2S options

%%

%% Preferred address families (which to try first) and connect timeout

%% in milliseconds.

%%

%% {outgoing_s2s_options, [ipv4, ipv6], 10000}.



%%%. ==============

%%% 'AUTHENTICATION



%%

%% auth_method: Method used to authenticate the users.

%% The default method is the internal.

%% If you want to use a different method,

%% comment this line and enable the correct ones.

%%

%% {auth_method, internal}.

%%

%% Store the plain passwords or hashed for SCRAM:

%% {auth_password_format, plain}.

%% {auth_password_format, scram}.

%%

%% Define the FQDN if ejabberd does not detect it:

%% {fqdn, "server3.example.com"}.



%%

%% Authentication using external script

%% Make sure the script is executable by ejabberd.

%%

%% {auth_method, external}.

%% {extauth_program, "/ path / to / authentication / script"}.



%%

%% Authentication using ODBC

%% Remember to setup a database in the next section.

%%

%% {auth_method, odbc}.



%%

%% Authentication using PAM

%%

%% {auth_method, pam}.

%% {pam_service, "ejabberd"}.



%%

%% Authentication using LDAP

%%



%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

%% Connect to AD 2008. For a list of users.

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

{auth_method, ldap}.



{ldap_servers, ["192.168.151.2"]}.

{ldap_port, 389}.



{ldap_uids, [{"sAMAccountName", "% u"}]}.

{ldap_filter, "(objectCategory = person)"}.



{ldap_base, "DC = developer, DC = com"}.

{ldap_rootdn, "userjabber@developer.com"}.

{ldap_password, "123456"}.

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%



%%

%% List of LDAP servers:

%% {ldap_servers, ["localhost"]}.

%%

%% Encryption of connection to LDAP servers:

%% {ldap_encrypt, none}.

%% {ldap_encrypt, tls}.

%%

%% Port to connect to on LDAP servers:

%% {ldap_port, 389}.

%% {ldap_port, 636}.

%%

%% LDAP manager:

%% {ldap_rootdn, "dc = example, dc = com"}.

%%

%% Password of LDAP manager:

%% {ldap_password, "******"}.

%%

%% Search base of LDAP directory:

%% {ldap_base, "dc = example, dc = com"}.

%%

%% LDAP attribute that holds user ID:

%% {ldap_uids, [{"mail", "%u@mail.example.org"}]}.

%%

%% LDAP filter:

%% {ldap_filter, "(objectClass = shadowAccount)"}.



%%

%% Anonymous login support:

%% auth_method: anonymous

%% anonymous_protocol: sasl_anon | login_anon | both

%% allow_multiple_connections: true | false

%%

%% {host_config, "public.example.org", [{auth_method, anonymous},

%% {allow_multiple_connections, false},

%% {anonymous_protocol, sasl_anon}]}.

%%

%% To use both anonymous and internal authentication:

%%

%% {host_config, "public.example.org", [{auth_method, [internal, anonymous]}]}.



%%%. ==============

%%% 'DATABASE SETUP



%% ejabberd by default uses the internal database,

%% so you do not necessarily need this section.

%% This section provides configuration examples in case

%% you want to use other database backends.

%% Please consult the ejabberd Guide for details on database creation.



%%

%% MySQL server:

%%

%% {odbc_server, {mysql, “server”, “database”, “username”, “password”}}.

%%

%% If you want to specify the port:

%% {odbc_server, {mysql, "server", 1234, "database", "username", "password"}}.



%%

%% PostgreSQL server:

%%

%% {odbc_server, {pgsql, "server", "database", "username", "password"}}.

%%

%% If you want to specify the port:

%% {odbc_server, {pgsql, "server", 1234, "database", "username", "password"}}.

%%

%% If you use PostgreSQL, have a large database, and need a

%% faster but inexact replacement for "select count (*) from users"

%%

%% {pgsql_users_number_estimate, true}.



%%

%% ODBC compatible or MSSQL server:

%%

%% {odbc_server, "DSN = ejabberd; UID = ejabberd; PWD = ejabberd"}.



%%

For each virtual host

%%

%% {odbc_pool_size, 10}.



%%

%% Interval to make a dummy SQL request to keep the connections to the

%% database alive. Specify in seconds: for example 28800 means 8 hours

%%

%% {odbc_keepalive_interval, undefined}.



%%%. ===============

%%% 'TRAFFIC SHAPERS



%%

%% The "normal" shaper limits traffic speed to 1000 B / s

%%

{shaper, normal, {maxrate, 1000}}.



%%

%% The “fast” shaper limits traffic speed to 50000 B / s

%%

{shaper, fast, {maxrate, 50000}}.



%%

%% This option specifies the number of elements in the queue

%% of the FSM. Refer to the documentation for details.

%%

{max_fsm_queue, 1000}.



%%%. ====================

%%% 'ACCESS CONTROL LISTS



%%

%% The 'admin' ACL grants administrative privileges to XMPP accounts.

%% You can put.

%%

%% {acl, admin, {user, "aleksey", "localhost"}}.

%% {acl, admin, {user, "ermine", "example.org"}}.



%%

%% Blocked users

%%

%% {acl, blocked, {user, "baduser", "example.org"}}.

%% {acl, blocked, {user, "test"}}.



%%

%% Local users: don't modify this line.

%%

{acl, local, {user_regexp, ""}}.



%%

%% More examples of ACLs

%%

%% {acl, jabberorg, {server, "jabber.org"}}.

%% {acl, aleksey, {user, "aleksey", "jabber.ru"}}.

%% {acl, test, {user_regexp, "^ test"}}.

%% {acl, test, {user_glob, "test *"}}.



%%

%% Define specific ACLs in a virtual host.

%%

%% {host_config, "localhost",

%% [

%% {acl, admin, {user, "bob-local", "localhost"}}

%%]

%%}.



%%%. ============

%%% 'ACCESS RULES



%% Maximum number of simultaneous sessions allowed for a single user:

{access, max_user_sessions, [{10, all}]}.



%% Maximum number of offline messages that users can have:

{access, max_user_offline_messages, [{5000, admin}, {100, all}]}.



%% This rule allows access only for local users:

{access, local, [{allow, local}]}.



%% Only non-blocked users can use c2s connections:

{access, c2s, [{deny, blocked},

{allow, all}]}.



%% For C2S connections, all users except admins use the "normal" shaper

{access, c2s_shaper, [{none, admin},

{normal, all}]}.



%% All S2S connections use the “fast” shaper

{access, s2s_shaper, [{fast, all}]}.



%% Only admins can send announcement messages:

{access, announce, [{allow, admin}]].



%% Only admins can use the configuration interface:

{access, configure, [{allow, admin}]}.



%% Admins of this server are also admins of the MUC service:

{access, muc_admin, [{allow, admin}]}.



%% Only accounts of the local ejabberd server can create rooms:

{access, muc_create, [{allow, local}]}.



%% All users are allowed to use the MUC service:

{access, muc, [{allow, all}]}.



%% Only accounts on the local server can create Pubsub nodes:

{access, pubsub_createnode, [{allow, local}]}.



%% In-band registration allows registration of any possible username.

%% To disable in-band registration, replace 'allow' with 'deny'.

{access, register, [{allow, all}]}.



%% By default of the frequency of account registrations from the same IP

%% is limited to 1 account every 10 minutes. To disable, specify: infinity

%% {registration_timeout, 600}.



%%

%% Define specific access rules in a virtual host.

%%

%% {host_config, "localhost",

%% [

%% {access, c2s, [{allow, admin}, {deny, all}]},

%% {access, register, [{deny, all}]}

%%]

%%}.



%%%. ================

%%% 'DEFAULT LANGUAGE



%%

%% language: Default language used for server messages.

%%

{language, "en"}.



%%

%% Set a different default language in a virtual host.

%%

%% {host_config, "localhost",

%% [{language, "en"}]

%%}.



%%%. =======

%%% 'CAPTCHA



%%

%% Full path to a script that generates the image.

%%

%% {captcha_cmd, "/usr/lib64/ejabberd/priv/bin/captcha.sh"}.



%%

%% Host for the URL and port where ejabberd listens for CAPTCHA requests.

%%

%% {captcha_host, "example.org:5280"}.



%%

%% Limit CAPTCHA calls to avoid the DoS.

%%

%% {captcha_limit, 5}.



%%%. =======

%%% 'MODULES



%%

%% Modules enabled in all ejabberd virtual hosts.

%%

{modules,

[

{mod_adhoc, []},

{mod_announce, [{access, announce}]},% recommends mod_adhoc

{mod_blocking, []},% requires mod_privacy

{mod_caps, []},

{mod_configure, []},% requires mod_adhoc

{mod_disco, []},

%% {mod_echo, [{host, "echo.localhost"}]},

{mod_irc, []},

{mod_http_bind, []},

%% {mod_http_fileserver, [

%% {docroot, "/ var / www"},

%% {accesslog, "/var/log/ejabberd/access.log"}

%%]},

{mod_last, []},

{mod_muc, [

%% {host, "conference. @ HOST @"},

{access, muc},

{access_create, muc_create},

{access_persistent, muc_create},

{access_admin, muc_admin}

]},

%% {mod_muc_log, []},

{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},

{ignore_pep_from_offline, true},% resource resource coms, but XEP incompliant

%% {ignore_pep_from_offline, false},% XEP compliant, but increases resource comsumption

{last_item_cache, false},

{plugins, ["flat", "hometree", "pep"]}% pep requires mod_caps

]},

{mod_register, [

%%

%% Protect In-Band account registrations with CAPTCHA.

%%

%% {captcha_protected, true},



%%

%% Set the minimum informational entropy for passwords.

%%

%% {password_strength, 32},



%%

%% After successful registration, the user receives

%% a message with this subject and body.

%%

{welcome_message, {"Welcome!",

"Hi. \ NWelcome to this XMPP server."}},



%%

%% When a user registers, send a notification to

%% these XMPP accounts.

%%

%% {registration_watchers, ["admin1@example.org"]},



%%

%% clients accounts

%%

{ip_access, [{allow, "127.0.0.0/8"},

{deny, "0.0.0.0/0"}]},



%%

%% Local c2s or remote s2s users cannot register accounts

%%

%% {access_from, deny},



{access, register}

]},

%% {mod_register_web, [

%%

%% When a user registers, send a notification to

%% these XMPP accounts.

%%

%% {registration_watchers, ["admin1@example.org"]}

%%]},

{mod_roster, []},

%% {mod_service_log, []},

%% {mod_shared_roster, []},



%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

%% Roster from AD 2008.

%% Formation of the list of users by groups displayed in connected

%% customers. Belonging to the group is read from the properties of the account created

%% in AD 2008, the Organization tab, the Department field.

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

{mod_shared_roster_ldap,

[{ldap_groupattr, "department"},

{ldap_groupdesc, "department"},

{ldap_rfilter, "(objectCategory = person)"},

{ldap_memberattr, "sAMAccountName"},

{ldap_userdesc, "cn"}

]

},

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%



{mod_stats, []},

{mod_time, []},

%% {mod_vcard, []},



%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

%% Read the VCard fields of each user from AD 2008, i.e. fields which

%% is contained in user properties. Surnames, first names, etc.

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%



{mod_vcard_ldap,

[{ldap_vcard_map,

[{"NICKNAME", "% s", ["displayname"]},

{"GIVEN", "% s", ["givenName"]},

{"MIDDLE", "% s", ["initials"]},

{"FAMILY", "% s", ["sn"]},

{"FN", "% s", ["displayName"]},

{"EMAIL", "% s", ["mail"]},

{"ORGNAME", "% s", ["company"]},

{"ORGUNIT", "% s", ["department"]},

{"CTRY", "% s", ["c"]},

{"LOCALITY", "% s", ["l"]},

{"STREET", "% s", ["streetAddress"]},

{"REGION", "% s", ["st"]},

{"PCODE", "% s", ["postalCode"]},

{"TITLE", "% s", ["title"]},

{"URL", "% s", ["wWWHomePage"]},

{"DESC", "% s", ["description"]},

{"TEL", "% s", ["telephoneNumber"]}]},

{ldap_search_fields,

[{"User", "% u"},

{"Name", "givenName"},

{"Family Name", "sn"},

{"Email", "mail"},

{"Company", "company"},

{"Department", "department"},

{"Role", "title"},

{"Description", "description"},

{"Phone", "telephoneNumber"}]},

{ldap_search_reported,

[{"Full Name", "FN"},

{"Nickname", "NICKNAME"},

{"Email", "EMAIL"}]}

]

},

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%



{mod_version, []}

]}.



%%

%% Enable modules with custom options

%%

%% {host_config, "localhost",

%% [{{add, modules},

%% [

%% {mod_echo, [{host, "mirror.localhost"}]}

%%]

%%}

%%]}.



%%%.

%%% '



%%% $ Id $



%%% Local Variables:

%%% mode: erlang

%%% End:

%%% vim: set filetype = erlang tabstop = 8 foldmarker = %%% ', %%%. foldmethod = marker:





And do not forget to follow the syntax in the config (commas, brackets, periods). On many syntax errors can be peeped in the logs, if the service does not start.

Source: https://habr.com/ru/post/194582/



All Articles