Personal tools
You are here: Home Linux Instant Messaging ejabberd CentOS VM

ejabberd CentOS VM

A howto/as built for an ejabberd XMPP server on CentOS v5

Create a minimal CentOS v5 x86_64 VM. The VM has 512MBytes of RAM, but I suspect it could run with less. Install basic packages and disable services.

Ejabberd is part of the EPEL repository. Install EPEL, and then install the ejabberd package:

# rpm -Uvh http://download.fedora.redhat.com/pub/epel/5/x86_64/epel-release-5-3.noarch.rpm 
# yum install ejabberd

DNS Configuration

Configure DNS records for the XMPP client and server. This example uses DJB DNS, and a SRV record generation script. The public DNS server records are:

+xmpp-server.lucidsolutions.co.nz:123.255.40.190:86400
+xmpp-client.lucidsolutions.co.nz:123.255.40.190:86400
+conference.lucidsolutions.co.nz:123.255.40.190:86400
+pubsub.lucidsolutions.co.nz:123.255.40.190:86400
#
#  client SRV records
# make-srv -service _xmpp-client._tcp.lucidsolutions.co.nz -target xmpp-client.lucidsolutions.co.nz -port 5222 -priority 10
:_xmpp-client._tcp.lucidsolutions.co.nz:33:\000\012\000\000\024f\013xmpp-client\016lucidsolutions\002co\002nz\000
#
# server SRV records
# make-srv -service _xmpp-server._tcp.lucidsolutions.co.nz -target xmpp-server.lucidsolutions.co.nz -port 5269 -priority 10
:_xmpp-server._tcp.lucidsolutions.co.nz:33:\000\012\000\000\024\225\013xmpp-server\016lucidsolutions\002co\002nz\000

And the internal DNS server records are:

+xmpp-server.lucidsolutions.co.nz:192.168.0.13:86400
+xmpp-client.lucidsolutions.co.nz:192.168.0.13:86400
+conference.lucidsolutions.co.nz:192.168.0.13:86400
+pubsub.lucidsolutions.co.nz:192.168.0.13:86400
#
#  client SRV records
# make-srv -service _xmpp-client._tcp.lucidsolutions.co.nz -target xmpp-client.lucidsolutions.co.nz -port 5222 -priority 10
:_xmpp-client._tcp.lucidsolutions.co.nz:33:\000\012\000\000\024f\013xmpp-client\016lucidsolutions\002co\002nz\000
#
# server SRV records
# make-srv -service _xmpp-server._tcp.lucidsolutions.co.nz -target xmpp-server.lucidsolutions.co.nz -port 5269 -priority 10
:_xmpp-server._tcp.lucidsolutions.co.nz:33:\000\012\000\000\024\225\013xmpp-server\016lucidsolutions\002co\002nz\000

Firewall rules

Add ingress/egress rules to the local IPTables firewall to allow s2s and c2s communication. Note that ejabberd registers a name with the erlang port mapper service (epmd), which the ejabberdctl must be able to access. It uses the main machine interface (not the loopback interface), thus a permissive firewall rule is needed to allow access from the local machine (192.168.0.13) to the local machine. The port mapper is on TCP port 4369 and the random port listed with the port mapper (run '/usr/lib64/erlang/bin/epmd -names' to list).

# ejabberd web interface
-A tcpIn  -p tcp -m tcp --dport 5280 --source 192.168.0.0/24 -m state --state NEW -j ACCEPT

# xmpp-server (s2s)
-A tcpIn  -p tcp -m tcp --dport 5269 -m state --state NEW -j ACCEPT
-A tcpOut -p tcp -m tcp --dport 5269 -m state --state NEW -j ACCEPT

# xmpp-client (c2s)
-A tcpIn  -p tcp -m tcp --dport 5222 -m state --state NEW -j ACCEPT
-A tcpOut -p tcp -m tcp --dport 5222 -m state --state NEW -j ACCEPT

# erlang port mapper and endpoints (epmd - port 4369)
-A tcpIn  -p tcp -m tcp --dport 1024:65535 --source 192.168.0.13 --destination 192.168.0.13 -m state --state NEW -j ACCEPT
-A tcpOut -p tcp -m tcp --dport 1024:65535 --source 192.168.0.13 --destination 192.168.0.13 -m state --state NEW -j ACCEPT

Note: For IPv4, a two NAT rules need to be added to the firewall for TCP port 5222 and TCP port 5269.

Configure ejabberd

Edit the default configuration file '/etc/ejabberd/ejabberd.cfg'. This configuration is for a single domain (lucidsolutions.co.nz), with in-band registration disabled, using internal authentication, and SSL/TLS enabled. The changes are:

  • add domain name
  • name the client certificate file
  • mandate the use of TLS by clients
  • name the server to server certificate file
  • disable register support
  • disable the irc module
90c90
< {hosts, ["lucidsolutions.co.nz"]}.
---
> {hosts, ["localhost"]}.
117,118c117
<                       {certfile, "/etc/ejabberd/ejabberd-c2s.pem"}, starttls,
<                       starttls_required,
---
>                       %%{certfile, "/path/t/etc/ejabberd/ejabberd.pem"}, starttls,
164c163
< {s2s_use_starttls, true}.
---
> %%{s2s_use_starttls, true}.
169c168
< {s2s_certfile, "/path/t/etc/ejabberd/ejabberd-s2s.pem"}.
---
> %%{s2s_certfile, "/path/t/etc/ejabberd/ejabberd.pem"}.
326d324
< {acl, admin, {user, "admin", "lucidsolutions.co.nz"}}.
394c392
< {access, register, [{deny, all}]}.
---
> {access, register, [{allow, all}]}.
441c439
<   %%{mod_irc,    []},
---
>   {mod_irc,      []},

Generate key/certificates

Given the configuration above, two certificates need to be generated. For now generate self-signed certificates, but in the past I have used free certificates from xmpp.org.

Create a self signed s2s certificate. The certificate will be valid for 10 years, and has a common name (CN) of 'xmpp-server.lucidsolutions.co.nz' (which is the name returned from the SRV record in the DNS configuration above).

umask 277
openssl genrsa 4096 > server.key

openssl req -new -key server.key \
    -subj "/C=NZ/ST=Canterbury/L=Christchurch/O=Lucid Solutions/CN=xmpp-server.lucidsolutions.co.nz" \
    -out s2s.csr
openssl x509 -req -days 3650 -in s2s.csr -signkey server.key -out s2s.cert

cat server.key s2s.cert > ejabberd-s2s.pem
chown ejabberd:ejabberd ejabberd-s2s.pem


openssl req -new -key server.key \
    -subj "/C=NZ/ST=Canterbury/L=Christchurch/O=Lucid Solutions/CN=xmpp-client.lucidsolutions.co.nz" \
    -out c2s.csr
openssl x509 -req -days 3650 -in c2s.csr -signkey server.key -out c2s.cert

cat server.key c2s.cert > ejabberd-c2s.pem
chown ejabberd:ejabberd ejabberd-c2s.pem

Start the service

Start the ejabberd service running. This will start the 'beam' and 'epmd' processes.

# chkconfig ejabberd on
# service ejabberd  start 

Configure accounts

Administrator

Add the administrator account to the server. Since in-band account registration has been disabled in the configuration, this must be done via the ejabberdctl method.

# ejabberdctl register admin lucidsolutions.co.nz rfk0g7cksm2L7bEgRiaLMebWS4vHncmyh4o85R97TyW8BYOT

Add users

Use the web interface to browse to http://crimson.lucidsolutions.co.nz:5280/admin and add users as required. Use the admin account (above) to authenticate with the password used in the previous step.

ejabberd add/list users

 

 

Outstanding Issues

  • Use certificates from xmpp.org
  • Enable IPv6

 

Links

Appendices

 yum install ejabberd

# yum install ejabberd

Dependencies Resolved

=============================================================================
 Package                 Arch       Version          Repository        Size
=============================================================================
Installing:
 ejabberd                x86_64     2.0.3-1.el5      epel              767 k
Installing for dependencies:
 erlang                  x86_64     R12B-3.3.el5     epel               38 M
 fedora-usermgmt         noarch     0.8.91-1.el5     epel              6.6 k
 fedora-usermgmt-core    noarch     0.8.91-1.el5     epel              7.6 k
 fedora-usermgmt-default-fedora-setup  noarch     0.8.91-1.el5     epel              6.6 k
 fedora-usermgmt-shadow-utils  noarch     0.8.91-1.el5     epel              7.4 k
 libX11                  x86_64     1.0.3-9.el5      base              795 k
 libXau                  x86_64     1.0.1-3.1        base               18 k
 libXdmcp                x86_64     1.0.1-2.1        base               19 k
 tk                      x86_64     8.4.13-5.el5_1.1  base              901 k
 unixODBC                x86_64     2.2.11-7.1       base              835 k
 xorg-x11-filesystem     noarch     7.1-2.fc6        base              5.4 k

Transaction Summary
=============================================================================
Install     12 Package(s)
Update       0 Package(s)
Remove       0 Package(s)

Total download size: 42 M

ejabberd configuration

%%%
%%%               ejabberd configuration file
%%%

%%% The parameters used in this configuration file are explained in more detail
%%% in the ejabberd Installation and Operation Guide.
%%% Please consult the Guide in case of doubts, it is included in
%%% your copy of ejabberd, and is also available online at
%%% http://www.process-one.net/en/ejabberd/docs/

%%% This configuration file contains Erlang terms.
%%% In case you want to understand the syntax, here are the concepts:
%%%
%%%  - The character to comment 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 can have as many elements as you want,
%%%    and is enclosed in [], for example:
%%%      [http_poll, web_admin, tls]
%%%
%%%  - A keyword of ejabberd is a word in lowercase.
%%%    The strings are enclosed in "" and can have 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 old 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 Access Control Lists before new ones are added.
%%
%%override_acls.


%%%   =========
%%%   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 useful for developers: if an ejabberd process
%% consumes a lot of memory, send live notifications to these Jabber
%% 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, ["lucidsolutions.co.nz"]}.

%%
%% route_subdomains: Delegate subdomains to other Jabber server.
%% For example, if this ejabberd serves example.org and you want
%% to allow communication with a Jabber server called im.example.org.
%%
%%{route_subdomains, s2s}.


%%%   ===============
%%%   LISTENING PORTS

%%
%% listen: Which ports will ejabberd listen, which service handles it
%% and what options to start it with.
%%
{listen,
 [

  {5222, ejabberd_c2s, [

                        %%
                        %% If TLS is compiled and you installed a SSL
                        %% certificate, put the correct path to the
                        %% file and uncomment this line:
                        %%
                        {certfile, "/etc/ejabberd/ejabberd-c2s.pem"}, starttls,
                        starttls_required,

                        {access, c2s},
                        {shaper, c2s_shaper},
                        {max_stanza_size, 65536}
                       ]},

  %%
  %% To enable the old SSL connection method in port 5223:
  %%
  %%{5223, ejabberd_c2s, [
  %%                    {access, c2s},
  %%                    {shaper, c2s_shaper},
  %%                    {certfile, "/path/t/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"}]
  %%                        }
  %%                       ]},

  {5280, ejabberd_http, [
                         http_poll,
                         web_admin
                        ]}

 ]}.

%%
%% s2s_use_starttls: Enable STARTTLS + Dialback for S2S connections.
%% Allowed values are: true or false.
%% You must specify a certificate file.
%%
{s2s_use_starttls, true}.

%%
%% s2s_certfile: Specify a certificate file.
%%
{s2s_certfile, "/path/t/etc/ejabberd/ejabberd-s2s.pem"}.

%%
%% domain_certfile: Specify a different 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}.


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

%%
%% 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
%%
%%{auth_method, ldap}.
%%
%% List of LDAP servers:
%%{ldap_servers, ["localhost"]}.
%%
%% LDAP attribute that holds user ID:
%%{ldap_uids, [{"mail", "%u@mail.example.org"}]}.
%%
%% Search base of LDAP directory:
%%{ldap_base, "dc=example,dc=com"}.
%%
%% LDAP manager:
%%{ldap_rootdn, "dc=example,dc=com"}.
%%
%% Password to LDAP manager:
%%{ldap_password, "******"}.

%%
%% 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 uses by default the internal Mnesia database,
%% so you can avoid this section.
%% This section provides configuration examples in case
%% you want to use other database backends.
%% Please consult the ejabberd Guide for details about 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"}.

%%
%% Number of connections to open to the database for each virtual host
%%
%%{odbc_pool_size, 10}.

%%
%% Interval to make a dummy SQL request to keep alive the connections
%% to the database. Specify in seconds: for example 28800 means 8 hours
%%
%%{odbc_keepalive_interval, undefined}.


%%%   ===============
%%%   TRAFFIC SHAPERS

%%
%% The "normal" shaper limits traffic speed to 1.000 B/s
%%
{shaper, normal, {maxrate, 1000}}.

%%
%% The "fast" shaper limits traffic speed to 50.000 B/s
%%
{shaper, fast, {maxrate, 50000}}.


%%%   ====================
%%%   ACCESS CONTROL LISTS

%%
%% The 'admin' ACL grants administrative privileges to Jabber accounts.
%% You can put as many accounts as you want.
%%
%%{acl, admin, {user, "aleksey", "localhost"}}.
%%{acl, admin, {user, "ermine", "example.org"}}.
{acl, admin, {user, "admin", "lucidsolutions.co.nz"}}.

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

%% 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 "normal" shaper
{access, c2s_shaper, [{none, admin},
                      {normal, all}]}.

%% All S2S connections use "fast" shaper
{access, s2s_shaper, [{fast, all}]}.

%% Only admins can send announcement messages:
{access, announce, [{allow, admin}]}.

%% Only admins can use configuration interface:
{access, configure, [{allow, admin}]}.

%% Admins of this server are also admins of MUC service:
{access, muc_admin, [{allow, admin}]}.

%% All users are allowed to use MUC service:
{access, muc, [{allow, all}]}.

%% Everybody can create pubsub nodes
{access, pubsub_createnode, [{allow, all}]}.

%% In-band registration allows registration of any possible username.
%% To disable in-band registration, replace 'allow' with 'deny'.
{access, register, [{deny, all}]}.

%% By default frequency of account registrations from a the same IP
%% is limited to 1 account every 10 minutes. To disable put: 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, "ru"}]
%%}.


%%%   =======
%%%   MODULES

%%
%% Modules enabled in all ejabberd virtual hosts.
%%
{modules,
 [
  {mod_adhoc,    []},
  {mod_announce, [{access, announce}]}, % recommends mod_adhoc
  {mod_caps,     []},
  {mod_configure,[]}, % requires mod_adhoc
  {mod_disco,    []},
  %%{mod_echo,   [{host, "echo.localhost"}]},
  %%{mod_irc,    []},
  {mod_last,     []},
  {mod_muc,      [
                  %%{host, "conference.@HOST@"},
                  {access, muc},
                  {access_create, muc},
                  {access_persistent, muc},
                  {access_admin, muc_admin}
                 ]},
  %%{mod_muc_log,[]},
  {mod_offline,  []},
  {mod_privacy,  []},
  {mod_private,  []},
  %%{mod_proxy65,[]},
  {mod_pubsub,   [ % requires mod_caps
                  {access_createnode, pubsub_createnode},
                  {plugins, ["default", "pep"]}
                 ]},
  {mod_register, [
                  %%
                  %% After successful registration, the user receives
                  %% a message with this subject and body.
                  %%
                  {welcome_message, {"Welcome!",
                                     "Hi\nWelcome to this Jabber server."}},

                  %%
                  %% When a user registers, send a notification to
                  %% these Jabber accounts.
                  %%
                  %%{registration_watchers, ["admin1@example.org"]},

                  {access, register}
                 ]},
  {mod_roster,   []},
  %%{mod_service_log,[]},
  {mod_shared_roster,[]},
  {mod_stats,    []},
  {mod_time,     []},
  {mod_vcard,    []},
  {mod_version,  []}
 ]}.

%%
%% Enable modules with custom options in a specific virtual host
%%
%%{host_config, "localhost",
%% [{{add, modules},
%%   [
%%    {mod_echo, [{host, "mirror.localhost"}]}
%%   ]
%%  }
%% ]}.


%%% $Id: ejabberd.cfg.example 1733 2008-12-16 17:39:05Z badlop $

%%% Local Variables:
%%% mode: erlang
%%% End:
%%% vim: set filetype=erlang tabstop=8:

Document Actions