Remove old docker specs

This commit is contained in:
Christophe Romain 2018-01-11 10:19:56 +01:00
parent 465629d458
commit d6e1bc242c
28 changed files with 0 additions and 2059 deletions

View File

@ -1,120 +0,0 @@
FROM debian:jessie-slim
MAINTAINER Rafael Römhild <rafael@roemhild.de>
ENV EJABBERD_BRANCH=17.08 \
EJABBERD_USER=ejabberd \
EJABBERD_HTTPS=true \
EJABBERD_STARTTLS=true \
EJABBERD_S2S_SSL=true \
EJABBERD_HOME=/opt/ejabberd \
EJABBERD_DEBUG_MODE=false \
HOME=$EJABBERD_HOME \
PATH=$EJABBERD_HOME/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/local/sbin \
DEBIAN_FRONTEND=noninteractive \
XMPP_DOMAIN=localhost \
# Set default locale for the environment
LC_ALL=C.UTF-8 \
LANG=en_US.UTF-8 \
LANGUAGE=en_US.UTF-8
# Add ejabberd user and group
RUN groupadd -r $EJABBERD_USER \
&& useradd -r -m \
-g $EJABBERD_USER \
-d $EJABBERD_HOME \
$EJABBERD_USER
# Install packages and perform cleanup
RUN set -x \
&& buildDeps=' \
git-core \
build-essential \
automake \
libssl-dev \
zlib1g-dev \
libexpat-dev \
libyaml-dev \
libsqlite3-dev \
erlang-src erlang-dev \
' \
&& requiredAptPackages=' \
wget \
locales \
ldnsutils \
python2.7 \
python-jinja2 \
ca-certificates \
libyaml-0-2 \
erlang-base erlang-snmp erlang-ssl erlang-ssh erlang-webtool \
erlang-tools erlang-xmerl erlang-corba erlang-diameter erlang-eldap \
erlang-eunit erlang-ic erlang-odbc erlang-os-mon \
erlang-parsetools erlang-percept erlang-typer \
python-mysqldb \
imagemagick \
' \
&& apt-key adv \
--keyserver keys.gnupg.net \
--recv-keys 434975BD900CCBE4F7EE1B1ED208507CA14F4FCA \
&& apt-get update \
&& apt-get install -y $buildDeps $requiredAptPackages --no-install-recommends \
&& dpkg-reconfigure locales && \
locale-gen C.UTF-8 \
&& /usr/sbin/update-locale LANG=C.UTF-8 \
&& echo 'en_US.UTF-8 UTF-8' >> /etc/locale.gen \
&& locale-gen \
&& cd /tmp \
&& git clone https://github.com/processone/ejabberd.git \
--branch $EJABBERD_BRANCH --single-branch --depth=1 \
&& cd ejabberd \
&& chmod +x ./autogen.sh \
&& ./autogen.sh \
&& ./configure --enable-user=$EJABBERD_USER \
--enable-all \
--disable-tools \
--disable-pam \
&& make debug=$EJABBERD_DEBUG_MODE \
&& make install \
&& mkdir $EJABBERD_HOME/ssl \
&& mkdir $EJABBERD_HOME/conf \
&& mkdir $EJABBERD_HOME/backup \
&& mkdir $EJABBERD_HOME/upload \
&& mkdir $EJABBERD_HOME/database \
&& mkdir $EJABBERD_HOME/module_source \
&& cd $EJABBERD_HOME \
&& rm -rf /tmp/ejabberd \
&& rm -rf /usr/local/etc/ejabberd \
&& ln -sf $EJABBERD_HOME/conf /usr/local/etc/ejabberd \
&& chown -R $EJABBERD_USER: $EJABBERD_HOME \
&& rm -rf /var/lib/apt/lists/* \
&& apt-get purge -y --auto-remove $buildDeps
RUN wget -P /usr/local/share/ca-certificates/cacert.org http://www.cacert.org/certs/root.crt http://www.cacert.org/certs/class3.crt; \
update-ca-certificates
# Create logging directories
RUN mkdir -p /var/log/ejabberd
RUN touch /var/log/ejabberd/crash.log /var/log/ejabberd/error.log /var/log/ejabberd/erlang.log
# Wrapper for setting config on disk from environment
# allows setting things like XMPP domain at runtime
ADD ./docker/run.sh /sbin/run
# Add run scripts
ADD ./docker/scripts $EJABBERD_HOME/scripts
ADD https://raw.githubusercontent.com/rankenstein/ejabberd-auth-mysql/master/auth_mysql.py $EJABBERD_HOME/scripts/lib/auth_mysql.py
RUN chmod a+rx $EJABBERD_HOME/scripts/lib/auth_mysql.py
# Add config templates
ADD ./docker/conf /opt/ejabberd/conf
# Continue as user
USER $EJABBERD_USER
# Set workdir to ejabberd root
WORKDIR $EJABBERD_HOME
VOLUME ["$EJABBERD_HOME/database", "$EJABBERD_HOME/ssl", "$EJABBERD_HOME/backup", "$EJABBERD_HOME/upload"]
EXPOSE 4560 5222 5269 5280 5443
CMD ["start"]
ENTRYPOINT ["run"]

View File

@ -1,402 +0,0 @@
ejabberd container
- [Introduction](#introduction)
- [Version](#version)
- [Quick Start](#quick-start)
- [Usage](#usage)
- [Persistence](#persistence)
- [SSL Certificates](#ssl-certificates)
- [Base Image](#base-image)
- [Cluster Example](#cluster-example)
- [Runtime Configuration](#runtime-configuration)
- [Served Hostnames](#served-hostnames)
- [Authentication](#authentication)
- [Admins](#admins)
- [Users](#users)
- [SSL](#ssl)
- [Erlang](#erlang)
- [Modules](#modules)
- [Logging](#logging)
- [Mount Configurations](#mount-configurations)
- [Maintenance](#maintenance)
- [Register Users](#register-users)
- [Creating Backups](#creating-backups)
- [Restoring Backups](#restoring-backups)
- [Debug](#debug)
- [Erlang Shell](#erlang-shell)
- [System Shell](#system-shell)
- [System Commands](#system-commands)
- [Exposed Ports](#exposed-ports)
# Introduction
This [ejabberd][] docker container is based on the work done by [rroemhild][]. See more [in this blogpost][].
This container includes the necessary files to build your own containerized ejabberd,
but *IT IS NOT* used to generate official images on the docker [hub][].
This container is not maintained by [ProcessOne][].
[ProcessOne][] provides and maintain official containers on the docker [hub][], which targets developers for now and will becomes production ready in a near future.
These [new containers] allow to build and run ejabberd in a simple and lightweight environment.
[ejabberd]: https://www.ejabberd.im/
[rroemhild]: https://github.com/rroemhild/docker-ejabberd/
[in this blogpost]: https://blog.process-one.net/ejabberd-16-12/
[hub]: https://hub.docker.com/r/ejabberd/ecs/
[new containers]: https://github.com/processone/docker-ejabberd/
[ProcessOne]: https://www.process-one.net/
## Version
Current Version: `17.08`
Docker Tag Names are based on ejabberd versions in git [branches][] and [tags][]. The image tag `:latest` is based on the master branch.
[tags]: https://github.com/rroemhild/docker-ejabberd/tags
[branches]: https://github.com/rroemhild/docker-ejabberd/branches
# Quick Start
You can start of with the following container:
```bash
docker run -d \
--name "ejabberd" \
-p 5222:5222 \
-p 5269:5269 \
-p 5280:5280 \
-h 'xmpp.example.de' \
-e "XMPP_DOMAIN=example.de" \
-e "ERLANG_NODE=ejabberd" \
-e "EJABBERD_ADMINS=admin@example.de admin2@example.de" \
-e "EJABBERD_USERS=admin@example.de:password1234 admin2@example.de" \
-e "TZ=Europe/Berlin" \
rroemhild/ejabberd
```
or with the [docker-compose](examples/docker-compose/docker-compose.yml) example
```bash
wget https://raw.githubusercontent.com/rroemhild/docker-ejabberd/master/examples/docker-compose/docker-compose.yml
docker-compose up
```
# Usage
## Persistence
For storage of the application data, you can mount volumes at
* `/opt/ejabberd/ssl`
* `/opt/ejabberd/backup`
* `/opt/ejabberd/upload`
* `/opt/ejabberd/database`
or use a data container
```bash
docker create --name ejabberd-data rroemhild/ejabberd-data
docker run -d --name ejabberd --volumes-from ejabberd-data rroemhild/ejabberd
```
## SSL Certificates
TLS is enabled by default and the run script will auto-generate two snake-oil certificates during boot if you don't provide your SSL certificates.
To use your own certificates, there are two options.
1. Mount the volume `/opt/ejabberd/ssl` to a local directory with the `.pem` files:
* /tmp/ssl/host.pem (SERVER_HOSTNAME)
* /tmp/ssl/xmpp_domain.pem (XMPP_DOMAIN)
Make sure that the certificate and private key are in one `.pem` file. If one file is missing it will be auto-generated. I.e. you can provide your certificate for your **XMMP_DOMAIN** and use a snake-oil certificate for the `SERVER_HOSTNAME`.
2. Specify the certificates via environment variables: **EJABBERD_SSLCERT_HOST** and **EJABBERD_SSLCERT_EXAMPLE_COM**. For the
domain certificates, make sure you match the domain names given in **XMPP_DOMAIN** and replace dots and dashes with underscore.
## Base Image
Build your own ejabberd container image and add your config templates, certificates or [extend](#cluster-example) it for your needs.
```
FROM rroemhild/ejabberd
ADD ./ejabberd.yml.tpl /opt/ejabberd/conf/ejabberd.yml.tpl
ADD ./ejabberdctl.cfg.tpl /opt/ejabberd/conf/ejabberdctl.cfg.tpl
ADD ./example.com.pem /opt/ejabberd/ssl/example.com.pem
```
If you need root privileges switch to `USER root` and go back to `USER ejabberd` when you're done.
## Cluster Example
The [docker-compose-cluster](examples/docker-compose-cluster) example demonstrates how to extend this container image to setup a multi-master cluster.
# Runtime Configuration
You can additionally provide extra runtime configuration in a downstream image by replacing the config template `ejabberd.yml.tpl` with one based on this image's template and include extra interpolation of environment variables. The template is parsed by Jinja2 with the runtime environment (equivalent to Python's `os.environ` available as `env`).
## Served Hostnames
By default the container will serve the XMPP domain `localhost`. In order to serve a different domain at runtime, provide the **XMPP_DOMAIN** variable with a domain name. You can add more domains separated with whitespace.
```
XMPP_DOMAIN=example.ninja xyz.io test.com
```
## Authentication
Authentication methods can be set with the **EJABBERD_AUTH_METHOD** environment variable. The default authentication mode is `internal`.
Supported authentication methods:
* anonymous
* internal
* external
* ldap
Internal and anonymous authentication example:
```
EJABBERD_AUTH_METHOD=internal anonymous
```
[External authentication](http://docs.ejabberd.im/admin/guide/configuration/#external-script) example:
```
EJABBERD_AUTH_METHOD=external
EJABBERD_EXTAUTH_PROGRAM="/opt/ejabberd/scripts/authenticate-user.sh"
EJABBERD_EXTAUTH_INSTANCES=3
EJABBERD_EXTAUTH_CACHE=600
```
**EJABBERD_EXTAUTH_INSTANCES** must be an integer with a minimum value of 1. **EJABBERD_EXTAUTH_CACHE** can be set to "false" or an integer value representing cache time in seconds. Note that caching should not be enabled if internal auth is also enabled.
### Password format
The variable `EJABBERD_AUTH_PASSWORD_FORMAT` controls in which format user passwords are
stored. Possible values are `plain` and `scram`. The default is to store
[SCRAM](https://en.wikipedia.org/wiki/Salted_Challenge_Response_Authentication_Mechanism)bled
passwords, meaning that it is impossible to obtain the original plain password from the
stored information.
NOTE: SCRAM does not work with SIP/TURN foreign authentication methods. In this case, you
may have to disable the option. More details can be found here:
https://docs.ejabberd.im/admin/configuration/#internal
If using SCRAM with an SQL database that has plaintext passwords stored, use the command
```
ejabberdctl convert_to_scram example.org
```
to convert all your existing plaintext passwords to scrambled format.
### MySQL Authentication
Set `EJABBERD_AUTH_METHOD=external` and `EJABBERD_EXTAUTH_PROGRAM=/opt/ejabberd/scripts/lib/auth_mysql.py` to enable MySQL authentication. Use the following environment variables to configure the database connection and the layout of the database. Password changing, registration, and unregistration are optional features and are enabled only if the respective queries are provided.
- **AUTH_MYSQL_HOST**: The MySQL host
- **AUTH_MYSQL_USER**: Username to connect to the MySQL host
- **AUTH_MYSQL_PASSWORD**: Password to connect to the MySQL host
- **AUTH_MYSQL_DATABASE**: Database name where to find the user information
- **AUTH_MYSQL_HASHALG**: Format of the password in the database. Default is cleartext. Options are `crypt`, `md5`, `sha1`, `sha224`, `sha256`, `sha384`, `sha512`. `crypt` is recommended, as it is salted. When setting the password, `crypt` uses SHA-512 (prefix `$6$`).
- **AUTH_MYSQL_QUERY_GETPASS**: Get the password for a user. Use the placeholders `%(user)s`, `%(host)s`. Example: `SELECT password FROM users WHERE username = CONCAT(%(user)s, '@', %(host)s)`
- **AUTH_MYSQL_QUERY_SETPASS**: Update the password for a user. Leave empty to disable. Placeholder `%(password)s` contains the hashed password. Example: `UPDATE users SET password = %(password)s WHERE username = CONCAT(%(user)s, '@', %(host)s)`
- **AUTH_MYSQL_QUERY_REGISTER**: Register a new user. Leave empty to disable. Example: `INSERT INTO users ( username, password ) VALUES ( CONCAT(%(user)s, '@', %(host)s), %(password)s )`
- **AUTH_MYSQL_QUERY_UNREGISTER**: Removes a user. Leave empty to disable. Example: `DELETE FROM users WHERE username = CONCAT(%(user)s, '@', %(host)s)`
Note that the MySQL authentication script writes a debug log into the file `/var/log/ejabberd/extauth.log`. To get its content, execute the following command:
```bash
docker exec -ti ejabberd tail -n50 -f /var/log/ejabberd/extauth.log
```
To find out more about the mysql authentication script, check out the [ejabberd-auth-mysql](https://github.com/rankenstein/ejabberd-auth-mysql) repository.
### LDAP Auth
Full documentation http://docs.ejabberd.im/admin/guide/configuration/#ldap.
Connection
- **EJABBERD_LDAP_SERVERS**: List of IP addresses or DNS names of your LDAP servers. This option is required.
- **EJABBERD_LDAP_ENCRYPT**: The value `tls` enables encryption by using LDAP over SSL. The default value is: `none`.
- **EJABBERD_LDAP_TLS_VERIFY**: `false|soft|hard` This option specifies whether to verify LDAP server certificate or not when TLS is enabled. The default is `false` which means no checks are performed.
- **EJABBERD_LDAP_TLS_CACERTFILE**: Path to file containing PEM encoded CA certificates.
- **EJABBERD_LDAP_TLS_DEPTH**: Specifies the maximum verification depth when TLS verification is enabled. The default value is 1.
- **EJABBERD_LDAP_PORT**: The default port is `389` if encryption is disabled; and `636` if encryption is enabled.
- **EJABBERD_LDAP_ROOTDN**: Bind DN. The default value is "" which means anonymous connection.
- **EJABBERD_LDAP_PASSWORD**: Bind password. The default value is "".
- **EJABBERD_LDAP_DEREF_ALIASES**: `never|always|finding|searching`
Whether or not to dereference aliases. The default is `never`.
Authentication
- **EJABBERD_LDAP_BASE**: LDAP base directory which stores users accounts. This option is required.
- **EJABBERD_LDAP_UIDS**: `ldap_uidattr:ldap_uidattr_format` The default attributes are `uid:%u`.
- **EJABBERD_LDAP_FILTER**: RFC 4515 LDAP filter. The default Filter value is undefined.
- **EJABBERD_LDAP_DN_FILTER**: `{ Filter: FilterAttrs }` This filter is applied on the results returned by the main filter. By default ldap_dn_filter is undefined.
## Admins
Set one or more admin user (seperated by whitespace) with the **EJABBERD_ADMINS** environment variable. You can register admin users with the **EJABBERD_USERS** environment variable during container startup, use you favorite XMPP client or the `ejabberdctl` command line utility.
```
EJABBERD_ADMINS=admin@example.ninja
```
## Users
Automatically register users during container startup. Uses random password if you don't provide a password for the user. Format is `JID:PASSWORD`. Register more users separated with whitespace.
Register the admin user from **EJABBERD_ADMINS** with a give password:
```
EJABBERD_USERS=admin@example.ninja:password1234
```
Or without a random password printed to stdout (check container logs):
```
EJABBERD_USERS=admin@example.ninja
```
Register more than one user:
```
EJABBERD_USERS=admin@example.ninja:password1234 user1@test.com user1@xyz.io
```
## SSL
- **EJABBERD_SKIP_MAKE_SSLCERT**: Skip generating ssl certificates. Default: false
- **EJABBERD_SSLCERT_HOST**: SSL Certificate for the hostname.
- **EJABBERD_SSLCERT_EXAMPLE_COM**: SSL Certificates for XMPP domains.
- **EJABBERD_STARTTLS**: Set to `false` to disable StartTLS for client to server connections. Defaults
to `true`.
- **EJABBERD_S2S_SSL**: Set to `false` to disable SSL in server 2 server connections. Defaults to `true`.
- **EJABBERD_HTTPS**: If your proxy terminates SSL you may want to disable HTTPS on port 5280 and 5443. Defaults to `true`.
- **EJABBERD_PROTOCOL_OPTIONS_TLSV1**: Allow TLSv1 protocol. Defaults to `false`.
- **EJABBERD_PROTOCOL_OPTIONS_TLSV1_1**: Allow TLSv1.1 protocol. Defaults to `true`.
- **EJABBERD_CIPHERS**: Cipher suite. Defaults to `HIGH:!aNULL:!3DES`.
- **EJABBERD_DHPARAM**: Set to `true` to use or generate custom DH parameters. Defaults to `false`.
- **EJABBERD_SKIP_MAKE_DHPARAM**: Skip generating DH params. Default: false
## Erlang
- **ERLANG_NODE**: Allows to explicitly specify erlang node for ejabberd. Set to `ejabberd` lets erlang add the hostname. Defaults to `ejabberd@localhost`.
- **ERLANG_COOKIE**: Set erlang cookie. Defaults to auto-generated cookie.
- **ERLANG_OPTIONS**: Overwrite additional options passed to erlang while starting ejabberd.
## Modules
- **EJABBERD_SKIP_MODULES_UPDATE**: If you do not need to update ejabberd modules specs, skip the update task and speedup start. Defaults to `false`.
- **EJABBERD_MOD_MUC_ADMIN**: Activate the mod_muc_admin module. Defaults to `false`.
- **EJABBERD_MOD_ADMIN_EXTRA**: Activate the mod_muc_admin module. Defaults to `true`.
- **EJABBERD_REGISTER_TRUSTED_NETWORK_ONLY**: Only allow user registration from the trusted_network access rule. Defaults to `true`.
- **EJABBERD_MOD_VERSION**: Activate the mod_version module. Defaults to `true`.
- **EJABBERD_SOURCE_MODULES**: List of modules, which will be installed from sources localized in ${EJABBERD_HOME}/module_source.
- **EJABBERD_CONTRIB_MODULES**: List of modules, which will be installed from contrib repository.
- **EJABBERD_RESTART_AFTER_MODULE_INSTALL**: If any modules were installed, restart the server, if the option is enabled.
- **EJABBERD_CUSTOM_AUTH_MODULE_OVERRIDE**: If a custom module was defined for handling auth, we need to override the pre-defined auth methods in the config.
## Logging
Use the **EJABBERD_LOGLEVEL** environment variable to set verbosity. Defaults to `4` (Info).
```
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
```
## Mount Configurations
If you prefer to use your own configuration files and avoid passing docker environment variables (```-e```), you can do so by mounting a host directory.
Pass in an additional ```-v``` to the ```docker run``` command, like so:
```
docker run -d \
--name "ejabberd" \
-p 5222:5222 \
-p 5269:5269 \
-p 5280:5280 \
-h 'xmpp.example.de' \
-v /<host_path>/conf:/opt/ejabberd/conf \
rroemhild/ejabberd
```
Your ```/<host_path>/conf``` folder should look like so:
```
/<host_path>/conf/
├── ejabberdctl.cfg
├── ejabberd.yml
└── inetrc
```
Example configuration files can be downloaded from the ejabberd [github](https://github.com/rroemhild/ejabberd) page.
When these files exist in ```/opt/ejabberd/conf```, the run script will ignore the configuration templates.
# Maintenance
The `ejabberdctl` command is in the search path and can be run by:
```bash
docker exec CONTAINER ejabberdctl help
```
## Register Users
```bash
docker exec CONTAINER ejabberdctl register user XMPP_DOMAIN PASSWORD
```
## Creating Backups
Create a backupfile with ejabberdctl and copy the file from the container to localhost
```bash
docker exec CONTAINER ejabberdctl backup /opt/ejabberd/backup/ejabberd.backup
docker cp CONTAINER:/opt/ejabberd/backup/ejabberd.backup /tmp/ejabberd.backup
```
## Restoring Backups
Copy the backupfile from localhost to the running container and restore with ejabberdctl
```bash
docker cp /tmp/ejabberd.backup CONTAINER:/opt/ejabberd/backup/ejabberd.backup
docker exec CONTAINER ejabberdctl restore /opt/ejabberd/backup/ejabberd.backup
```
# Debug
## Erlang Shell
Set `-i` and `-t` option and append `live` to get an interactive erlang shell:
```bash
docker run -i -t -P rroemhild/ejabberd live
```
You can terminate the erlang shell with `q().`.
## System Shell
```bash
docker run -i -t rroemhild/ejabberd shell
```
## System Commands
```bash
docker run -i -t rroemhild/ejabberd env
```
# Exposed Ports
* 4560 (XMLRPC)
* 5222 (Client 2 Server)
* 5269 (Server 2 Server)
* 5280 (HTTP admin/websocket/http-bind)
* 5443 (HTTP Upload)

View File

@ -1,441 +0,0 @@
###
### 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 with
### your copy of ejabberd, and is also available online at
### http://www.process-one.net/en/ejabberd/docs/
### =======
### LOGGING
loglevel: {{ env['EJABBERD_LOGLEVEL'] or 4 }}
log_rotate_size: 10485760
log_rotate_count: 0
log_rate_limit: 100
## watchdog_admins:
## - "bob@example.com"
### ================
### SERVED HOSTNAMES
hosts:
{%- for xmpp_domain in env['XMPP_DOMAIN'].split() %}
- "{{ xmpp_domain }}"
{%- endfor %}
##
## 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:
-
port: 5222
module: ejabberd_c2s
{%- if env['EJABBERD_STARTTLS'] == "true" %}
starttls_required: true
{%- endif %}
protocol_options:
- "no_sslv3"
{%- if env.get('EJABBERD_PROTOCOL_OPTIONS_TLSV1', "false") == "false" %}
- "no_tlsv1"
{%- endif %}
{%- if env.get('EJABBERD_PROTOCOL_OPTIONS_TLSV1_1', "true") == "false" %}
- "no_tlsv1_1"
{%- endif %}
max_stanza_size: 65536
shaper: c2s_shaper
access: c2s
ciphers: "{{ env.get('EJABBERD_CIPHERS', 'HIGH:!aNULL:!3DES') }}"
{%- if env.get('EJABBERD_DHPARAM', false) == "true" %}
dhfile: "/opt/ejabberd/ssl/dh.pem"
{%- endif %}
-
port: 5269
module: ejabberd_s2s_in
-
port: 4560
module: ejabberd_xmlrpc
access_commands:
configure:
all: []
-
port: 5280
module: ejabberd_http
request_handlers:
"/websocket": ejabberd_http_ws
## "/pub/archive": mod_http_fileserver
web_admin: true
http_bind: true
## register: true
captcha: true
{%- if env['EJABBERD_HTTPS'] == "true" %}
tls: true
certfile: "/opt/ejabberd/ssl/host.pem"
{% endif %}
-
port: 5443
module: ejabberd_http
request_handlers:
"": mod_http_upload
{%- if env['EJABBERD_HTTPS'] == "true" %}
tls: true
certfile: "/opt/ejabberd/ssl/host.pem"
{% endif %}
### SERVER TO SERVER
### ================
{%- if env['EJABBERD_S2S_SSL'] == "true" %}
s2s_use_starttls: required
s2s_certfile: "/opt/ejabberd/ssl/host.pem"
s2s_protocol_options:
- "no_sslv3"
{%- if env.get('EJABBERD_PROTOCOL_OPTIONS_TLSV1', "false") == "false" %}
- "no_tlsv1"
{%- endif %}
{%- if env.get('EJABBERD_PROTOCOL_OPTIONS_TLSV1_1', "true") == "false" %}
- "no_tlsv1_1"
{%- endif %}
s2s_ciphers: "{{ env.get('EJABBERD_CIPHERS', 'HIGH:!aNULL:!3DES') }}"
{%- if env.get('EJABBERD_DHPARAM', false) == "true" %}
s2s_dhfile: "/opt/ejabberd/ssl/dh.pem"
{%- endif %}
{% endif %}
### ==============
### AUTHENTICATION
auth_method:
{%- for auth_method in env.get('EJABBERD_AUTH_METHOD', 'internal').split() %}
- {{ auth_method }}
{%- endfor %}
auth_password_format: {{ env.get('EJABBERD_AUTH_PASSWORD_FORMAT', 'scram') }}
{%- if 'anonymous' in env.get('EJABBERD_AUTH_METHOD', 'internal').split() %}
anonymous_protocol: both
allow_multiple_connections: true
{%- endif %}
## LDAP authentication
{%- if 'ldap' in env.get('EJABBERD_AUTH_METHOD', 'internal').split() %}
ldap_servers:
{%- for ldap_server in env.get('EJABBERD_LDAP_SERVERS', 'internal').split() %}
- "{{ ldap_server }}"
{%- endfor %}
ldap_encrypt: {{ env.get('EJABBERD_LDAP_ENCRYPT', 'none') }}
ldap_tls_verify: {{ env.get('EJABBERD_LDAP_TLS_VERIFY', 'false') }}
{%- if env['EJABBERD_LDAP_TLS_CACERTFILE'] %}
ldap_tls_cacertfile: "{{ env['EJABBERD_LDAP_TLS_CACERTFILE'] }}"
{%- endif %}
ldap_tls_depth: {{ env.get('EJABBERD_LDAP_TLS_DEPTH', 1) }}
{%- if env['EJABBERD_LDAP_PORT'] %}
ldap_port: {{ env['EJABBERD_LDAP_PORT'] }}
{%- endif %}
{%- if env['EJABBERD_LDAP_ROOTDN'] %}
ldap_rootdn: "{{ env['EJABBERD_LDAP_ROOTDN'] }}"
{%- endif %}
{%- if env['EJABBERD_LDAP_PASSWORD'] %}
ldap_password: "{{ env['EJABBERD_LDAP_PASSWORD'] }}"
{%- endif %}
ldap_deref_aliases: {{ env.get('EJABBERD_LDAP_DEREF_ALIASES', 'never') }}
ldap_base: "{{ env['EJABBERD_LDAP_BASE'] }}"
{%- if env['EJABBERD_LDAP_UIDS'] %}
ldap_uids:
{%- for ldap_uid in env['EJABBERD_LDAP_UIDS'].split() %}
"{{ ldap_uid.split(':')[0] }}": "{{ ldap_uid.split(':')[1] }}"
{%- endfor %}
{%- endif %}
{%- if env['EJABBERD_LDAP_FILTER'] %}
ldap_filter: "{{ env['EJABBERD_LDAP_FILTER'] }}"
{%- endif %}
{%- if env['EJABBERD_LDAP_DN_FILTER'] %}
ldap_dn_filter:
{%- for dn_filter in env['EJABBERD_LDAP_DN_FILTER'].split() %}
"{{ dn_filter.split(':')[0] }}": ["{{ dn_filter.split(':')[1] }}"]
{%- endfor %}
{%- endif %}
{%- endif %}
{%- if 'external' in env.get('EJABBERD_AUTH_METHOD', 'internal').split() %}
{%- if env['EJABBERD_EXTAUTH_PROGRAM'] %}
extauth_program: "{{ env['EJABBERD_EXTAUTH_PROGRAM'] }}"
{%- endif %}
{%- if env['EJABBERD_EXTAUTH_INSTANCES'] %}
extauth_instances: {{ env['EJABBERD_EXTAUTH_INSTANCES'] }}
{%- endif %}
{%- if 'internal' in env.get('EJABBERD_AUTH_METHOD').split() %}
extauth_cache: false
{%- elif env['EJABBERD_EXTAUTH_CACHE'] %}
extauth_cache: {{ env['EJABBERD_EXTAUTH_CACHE'] }}
{%- endif %}
{% endif %}
### ===============
### TRAFFIC SHAPERS
shaper:
normal: 1000
fast: 50000
max_fsm_queue: 1000
### ====================
### ACCESS CONTROL LISTS
acl:
admin:
user:
{%- if env['EJABBERD_ADMINS'] %}
{%- for admin in env['EJABBERD_ADMINS'].split() %}
- "{{ admin.split('@')[0] }}": "{{ admin.split('@')[1] }}"
{%- endfor %}
{%- else %}
- "admin": "{{ env['XMPP_DOMAIN'].split()[0] }}"
{%- endif %}
local:
user_regexp: ""
### ============
### ACCESS RULES
access:
## Maximum number of simultaneous sessions allowed for a single user:
max_user_sessions:
all: 10
## Maximum number of offline messages that users can have:
max_user_offline_messages:
admin: 5000
all: 100
## This rule allows access only for local users:
local:
local: allow
## Only non-blocked users can use c2s connections:
c2s:
blocked: deny
all: allow
## For C2S connections, all users except admins use the "normal" shaper
c2s_shaper:
admin: none
all: normal
## All S2S connections use the "fast" shaper
s2s_shaper:
all: fast
## Only admins can send announcement messages:
announce:
admin: allow
## Only admins can use the configuration interface:
configure:
admin: allow
## Admins of this server are also admins of the MUC service:
muc_admin:
admin: allow
## Only accounts of the local ejabberd server, or only admins can create rooms, depending on environment variable:
muc_create:
{%- if env['EJABBERD_MUC_CREATE_ADMIN_ONLY'] == "true" %}
admin: allow
{% else %}
local: allow
{% endif %}
## All users are allowed to use the MUC service:
muc:
all: allow
## Only accounts on the local ejabberd server can create Pubsub nodes:
pubsub_createnode:
local: allow
## In-band registration allows registration of any possible username.
register:
{%- if env['EJABBERD_REGISTER_ADMIN_ONLY'] == "true" %}
all: deny
admin: allow
{% else %}
all: allow
{% endif %}
## Only allow to register from localhost
trusted_network:
loopback: allow
soft_upload_quota:
all: 400 # MiB
hard_upload_quota:
all: 500 # MiB
language: "en"
### =======
### MODULES
modules:
mod_adhoc: {}
{%- if env['EJABBERD_MOD_ADMIN_EXTRA'] == "true" %}
mod_admin_extra: {}
{% endif %}
mod_announce: # recommends mod_adhoc
access: announce
mod_blocking: {} # requires mod_privacy
mod_caps: {}
mod_carboncopy: {}
mod_client_state:
queue_chat_states: true
queue_presence: false
mod_configure: {} # requires mod_adhoc
mod_disco: {}
## mod_echo: {}
mod_irc: {}
mod_http_bind: {}
## mod_http_fileserver:
## docroot: "/var/www"
## accesslog: "/var/log/ejabberd/access.log"
mod_last: {}
mod_mam:
default: always
mod_muc:
host: "conference.@HOST@"
access: muc
access_create: muc_create
access_persistent: muc_create
access_admin: muc_admin
history_size: 50
default_room_options:
persistent: true
{%- if env['EJABBERD_MOD_MUC_ADMIN'] == "true" %}
mod_muc_admin: {}
{% endif %}
## mod_muc_log: {}
## mod_multicast: {}
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
## reduces resource comsumption, but XEP incompliant
ignore_pep_from_offline: true
## XEP compliant, but increases resource comsumption
## ignore_pep_from_offline: false
last_item_cache: false
plugins:
- "flat"
- "hometree"
- "pep" # pep requires mod_caps
mod_push: {}
mod_push_keepalive: {}
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:
subject: "Welcome!"
body: |-
Hi.
Welcome to this XMPP server.
##
## Only clients in the server machine can register accounts
##
{%- if env['EJABBERD_REGISTER_TRUSTED_NETWORK_ONLY'] == "true" %}
ip_access: trusted_network
{% endif %}
access: register
mod_roster: {}
mod_shared_roster: {}
mod_stats: {}
mod_time: {}
mod_vcard: {}
{% if env.get('EJABBERD_MOD_VERSION', true) == "true" %}
mod_version: {}
{% endif %}
mod_http_upload:
docroot: "/opt/ejabberd/upload"
{%- if env['EJABBERD_HTTPS'] == "true" %}
put_url: "https://@HOST@:5443"
{%- else %}
put_url: "http://@HOST@:5443"
{% endif %}
mod_http_upload_quota:
max_days: 10
### ============
### HOST CONFIG
host_config:
{%- for xmpp_domain in env['XMPP_DOMAIN'].split() %}
"{{ xmpp_domain }}":
domain_certfile: "/opt/ejabberd/ssl/{{ xmpp_domain }}.pem"
{%- endfor %}
{%- if env['EJABBERD_CONFIGURE_ODBC'] == "true" %}
### ====================
### ODBC DATABASE CONFIG
sql_type: {{ env['EJABBERD_ODBC_TYPE'] }}
sql_server: "{{ env['EJABBERD_ODBC_SERVER'] }}"
sql_database: "{{ env['EJABBERD_ODBC_DATABASE'] }}"
sql_username: "{{ env['EJABBERD_ODBC_USERNAME'] }}"
sql_password: "{{ env['EJABBERD_ODBC_PASSWORD'] }}"
default_db: sql
{% endif %}
{%- if env['EJABBERD_DEFAULT_DB'] is defined %}
default_db: {{ env['EJABBERD_DEFAULT_DB'] }}
{% endif %}
### =====================
### SESSION MANAGEMENT DB
sm_db_type: {{ env['EJABBERD_SESSION_DB'] or "mnesia" }}
{%- if env['EJABBERD_CONFIGURE_REDIS'] == "true" %}
### ====================
### REDIS DATABASE CONFIG
redis_server: {{ env['EJABBERD_REDIS_SERVER'] or "localhost" }}
redis_port: {{ env['EJABBERD_REDIS_PORT'] or 6379 }}
{%- if env['EJABBERD_REDIS_PASSWORD'] is defined %}
redis_password: {{ env['EJABBERD_REDIS_PASSWORD'] }}
{% endif %}
redis_db: {{ env['EJABBERD_REDIS_DB'] or 0}}
redis_reconnect_timeout: {{ env['EJABBERD_REDIS_RECONNECT_TIMEOUT'] or 1 }}
redis_connect_timeout: {{ env['EJABBERD_REDIS_CONNECT_TIMEOUT'] or 1 }}
{% endif %}

View File

@ -1,187 +0,0 @@
#
# In this file you can configure options that are passed by ejabberdctl
# to the erlang runtime system when starting ejabberd
#
#' POLL: Kernel polling ([true|false])
#
# The kernel polling option requires support in the kernel.
# Additionally, you need to enable this feature while compiling Erlang.
#
# Default: true
#
#POLL=true
#.
#' SMP: SMP support ([enable|auto|disable])
#
# Explanation in Erlang/OTP documentation:
# enable: starts the Erlang runtime system with SMP support enabled.
# This may fail if no runtime system with SMP support is available.
# auto: starts the Erlang runtime system with SMP support enabled if it
# is available and more than one logical processor are detected.
# disable: starts a runtime system without SMP support.
#
# Default: auto
#
#SMP=auto
#.
#' ERL_MAX_PORTS: Maximum number of simultaneously open Erlang ports
#
# ejabberd consumes two or three ports for every connection, either
# from a client or from another Jabber server. So take this into
# account when setting this limit.
#
# Default: 32000
# Maximum: 268435456
#
#ERL_MAX_PORTS=32000
#.
#' FIREWALL_WINDOW: Range of allowed ports to pass through a firewall
#
# If Ejabberd is configured to run in cluster, and a firewall is blocking ports,
# it's possible to make Erlang use a defined range of port (instead of dynamic
# ports) for node communication.
#
# Default: not defined
# Example: 4200-4210
#
#FIREWALL_WINDOW=
#.
#' INET_DIST_INTERFACE: IP address where this Erlang node listens other nodes
#
# This communication is used by ejabberdctl command line tool,
# and in a cluster of several ejabberd nodes.
#
# Default: 127.0.0.1
#
#INET_DIST_INTERFACE=127.0.0.1
#.
#' ERL_EPMD_ADDRESS: IP addresses where epmd listens for connections
#
# IMPORTANT: This option works only in Erlang/OTP R14B03 and newer.
#
# This environment variable may be set to a comma-separated
# list of IP addresses, in which case the epmd daemon
# will listen only on the specified address(es) and on the
# loopback address (which is implicitly added to the list if it
# has not been specified). The default behaviour is to listen on
# all available IP addresses.
#
# Default: 0.0.0.0
#
#ERL_EPMD_ADDRESS=127.0.0.1
#.
#' ERL_PROCESSES: Maximum number of Erlang processes
#
# Erlang consumes a lot of lightweight processes. If there is a lot of activity
# on ejabberd so that the maximum number of processes is reached, people will
# experience greater latency times. As these processes are implemented in
# Erlang, and therefore not related to the operating system processes, you do
# not have to worry about allowing a huge number of them.
#
# Default: 250000
# Maximum: 268435456
#
#ERL_PROCESSES=250000
#.
#' ERL_MAX_ETS_TABLES: Maximum number of ETS and Mnesia tables
#
# The number of concurrent ETS and Mnesia tables is limited. When the limit is
# reached, errors will appear in the logs:
# ** Too many db tables **
# You can safely increase this limit when starting ejabberd. It impacts memory
# consumption but the difference will be quite small.
#
# Default: 1400
#
#ERL_MAX_ETS_TABLES=1400
#.
#' ERL_OPTIONS: Additional Erlang options
#
# The next variable allows to specify additional options passed to erlang while
# starting ejabberd. Some useful options are -noshell, -detached, -heart. When
# ejabberd is started from an init.d script options -noshell and -detached are
# added implicitly. See erl(1) for more info.
#
# It might be useful to add "-pa /usr/local/lib/ejabberd/ebin" if you
# want to add local modules in this path.
#
# Default: ""
#
ERL_OPTIONS="{{ env['ERL_OPTIONS'] or "-noshell" }}"
#.
#' ERLANG_NODE: Erlang node name
#
# The next variable allows to explicitly specify erlang node for ejabberd
# It can be given in different formats:
# ERLANG_NODE=ejabberd
# Lets erlang add hostname to the node (ejabberd uses short name in this case)
# ERLANG_NODE=ejabberd@hostname
# Erlang uses node name as is (so make sure that hostname is a real
# machine hostname or you'll not be able to control ejabberd)
# ERLANG_NODE=ejabberd@hostname.domainname
# The same as previous, but erlang will use long hostname
# (see erl (1) manual for details)
#
# Default: ejabberd@localhost
#
ERLANG_NODE={{ env['ERLANG_NODE'] or "ejabberd@localhost" }}
#.
#' EJABBERD_PID_PATH: ejabberd PID file
#
# Indicate the full path to the ejabberd Process identifier (PID) file.
# If this variable is defined, ejabberd writes the PID file when starts,
# and deletes it when stops.
# Remember to create the directory and grant write permission to ejabberd.
#
# Default: don't write PID file
#
#EJABBERD_PID_PATH=/var/run/ejabberd/ejabberd.pid
#.
#' EJABBERD_CONFIG_PATH: ejabberd configuration file
#
# Specify the full path to the ejabberd configuration file. If the file name has
# yml or yaml extension, it is parsed as a YAML file; otherwise, Erlang syntax is
# expected.
#
# Default: $ETC_DIR/ejabberd.yml
#
#EJABBERD_CONFIG_PATH=/etc/ejabberd/ejabberd.yml
#.
#' CONTRIB_MODULES_PATH: contributed ejabberd modules path
#
# Specify the full path to the contributed ejabberd modules. If the path is not
# defined, ejabberd will use ~/.ejabberd-modules in home of user running ejabberd.
#
# Default: $HOME/.ejabberd-modules
#
#CONTRIB_MODULES_PATH=/opt/ejabberd-modules
#.
#' EJABBERD_BYPASS_WARNINGS: Bypass LIVE warning
#
# Default: don't bypass the warning
#
EJABBERD_BYPASS_WARNINGS=true
#.
#' SPOOL_DIR: Database spool dir
#
# Specify the full path to the database spool dir used in binary installer for
# backwards compatibility.
#
# Docker: rroemhild/ejabberd
#
SPOOL_DIR=$EJABBERD_HOME/database/$ERLANG_NODE

View File

@ -1,3 +0,0 @@
{lookup,["file","native"]}.
{host,{127,0,0,1}, ["localhost","hostalias"]}.
{file, resolv, "/etc/resolv.conf"}.

View File

@ -1,3 +0,0 @@
FROM rroemhild/ejabberd
ENV EJABBERD_HOME /opt/ejabberd
COPY ./scripts $EJABBERD_HOME/scripts

View File

@ -1,23 +0,0 @@
# Ejabberd cluster with docker compose
This example uses [dnsdocker](https://github.com/tonistiigi/dnsdock) to discover other nodes and setup a multi-master cluster.
Build the ejabberd cluster image:
```bash
git clone https://github.com/rroemhild/docker-ejabberd.git
cd docker-ejabberd/examples/docker-compose-cluster
docker-compose build
```
Start dnsdocker and the first ejabberd node:
```bash
docker-compose up -d
```
Wait until the first ejabberd node is up and running `docker-compose logs ejabberd`, then add some ejabberd nodes to the cluster:
```bash
docker-compose scale ejabberd=4
```

View File

@ -1,25 +0,0 @@
dnsdock:
image: tonistiigi/dnsdock
volumes:
- /var/run/docker.sock:/var/run/docker.sock
ports:
- 172.17.42.1:53:53/udp
ejabberd:
build: .
ports:
- 5222
- 5269
- 5280
environment:
- XMPP_DOMAIN=example.com
- ERLANG_NODE=ejabberd
- EJABBERD_ADMINS=admin@example.com
- EJABBERD_USERS=admin@example.com:test321 user@example.com
- ERLANG_COOKIE=testCluster
- SKIP_MODULES_UPDATE=true
- EJABBERD_CLUSTER=true
- USE_DNS=true
dns: 172.17.42.1
domainname: dockercomposecluster_ejabberd.docker
tty: true

View File

@ -1,37 +0,0 @@
# overwrite get_nodename to discover hostname from DNS
get_nodename() {
local hostname=${HOSTNAME}
# get hostname from dns
if ( is_true ${USE_DNS} ); then
# wait for dns registration
sleep 1
nodename=$(discover_dns_hostname ${HOSTIP})
is_set ${nodename} \
&& hostname=${nodename}
fi
echo $hostname
return 0
}
# discover hostname from dns with a reverse lookup
discover_dns_hostname() {
local hostip=$1
# try to get the hostname from dns
local dnsname=$(drill -x ${hostip} \
| grep PTR \
| awk '{print $5}' \
| grep -E "^[a-zA-Z0-9]+([-._]?[a-zA-Z0-9]+)*.[a-zA-Z]+\.$" \
| cut -d '.' -f1 \
| tail -1)
is_set ${dnsname} \
&& echo ${dnsname}
return 0
}

View File

@ -1,28 +0,0 @@
#!/bin/bash
set -e
source "${EJABBERD_HOME}/scripts/lib/base_config.sh"
source "${EJABBERD_HOME}/scripts/lib/config.sh"
source "${EJABBERD_HOME}/scripts/lib/base_functions.sh"
source "${EJABBERD_HOME}/scripts/lib/functions.sh"
get_cluster_node_from_dns() {
local cluster_host=$(drill ${DOMAINNAME} \
| grep ${DOMAINNAME} \
| grep -v ${HOSTIP} \
| awk '{print $5}' \
| grep -v "^$" \
| head -1)
echo $(discover_dns_hostname ${cluster_host})
}
file_exist ${FIRST_START_DONE_FILE} \
&& exit 0
join_cluster $(get_cluster_node_from_dns)
exit 0

View File

@ -1 +0,0 @@
# simple docker-compose example

View File

@ -1,11 +0,0 @@
ejabberd:
image: rroemhild/ejabberd
ports:
- 5222:5222
- 5269:5269
- 5280:5280
environment:
- ERLANG_NODE=ejabberd
- XMPP_DOMAIN=example.com xyz.io
- EJABBERD_ADMINS=admin@example.com
- EJABBERD_USERS=admin@example.com:password4321 user1@xyz.io

View File

@ -1,99 +0,0 @@
#!/bin/bash
set -e
source "${EJABBERD_HOME}/scripts/lib/base_config.sh"
source "${EJABBERD_HOME}/scripts/lib/config.sh"
source "${EJABBERD_HOME}/scripts/lib/base_functions.sh"
source "${EJABBERD_HOME}/scripts/lib/functions.sh"
# discover hostname
readonly nodename=$(get_nodename)
is_zero ${ERLANG_NODE} \
&& export ERLANG_NODE="ejabberd@localhost"
## backward compatibility
# if ERLANG_NODE is true reset it to "ejabberd" and add
# hostname to the nodename.
# else: export ${ERLANG_NODE} with nodename
if (is_true ${ERLANG_NODE}); then
export ERLANG_NODE="ejabberd@${nodename}"
fi
run_scripts() {
local run_script_dir="${EJABBERD_HOME}/scripts/${1}"
for script in ${run_script_dir}/*.sh ; do
if [ -f ${script} -a -x ${script} ] ; then
${script}
fi
done
}
pre_scripts() {
run_scripts "pre"
}
post_scripts() {
run_scripts "post"
}
stop_scripts() {
run_scripts "stop"
}
ctl() {
local action="$1"
${EJABBERDCTL} ${action} >/dev/null
}
_trap() {
echo "Stopping ejabberd..."
stop_scripts
if ctl stop ; then
local cnt=0
sleep 1
while ctl status || test $? = 1 ; do
cnt=`expr $cnt + 1`
if [ $cnt -ge 60 ] ; then
break
fi
sleep 1
done
fi
}
# Catch signals and shutdown ejabberd
trap _trap SIGTERM SIGINT
## run ejabberd
case "$@" in
start)
pre_scripts
tail -n 0 -F ${LOGDIR}/crash.log \
${LOGDIR}/error.log \
${LOGDIR}/erlang.log &
echo "Starting ejabberd..."
exec ${EJABBERDCTL} "foreground" &
child=$!
${EJABBERDCTL} "started"
post_scripts
wait $child
;;
live)
pre_scripts
echo "Starting ejabberd in 'live' mode..."
exec ${EJABBERDCTL} "live"
;;
shell)
exec "/bin/bash"
;;
*)
exec $@
;;
esac

View File

@ -1,53 +0,0 @@
readonly HOSTIP=$(hostname -i)
readonly HOSTNAME=$(hostname -f)
readonly DOMAINNAME=$(hostname -d)
readonly ERLANGCOOKIEFILE="${EJABBERD_HOME}/.erlang.cookie"
readonly EJABBERDCTL="/usr/local/sbin/ejabberdctl"
readonly CONFIGFILE="${EJABBERD_HOME}/conf/ejabberd.yml"
readonly CONFIGTEMPLATE="${EJABBERD_HOME}/conf/ejabberd.yml.tpl"
readonly CTLCONFIGFILE="${EJABBERD_HOME}/conf/ejabberdctl.cfg"
readonly CTLCONFIGTEMPLATE="${EJABBERD_HOME}/conf/ejabberdctl.cfg.tpl"
readonly SSLCERTDIR="${EJABBERD_HOME}/ssl"
readonly SSLCERTHOST="${SSLCERTDIR}/host.pem"
readonly SSLDHPARAM="${SSLCERTDIR}/dh.pem"
readonly LOGDIR="/usr/local/var/log/ejabberd"
readonly FIRST_START_DONE_FILE="/${EJABBERD_HOME}/first-start-done"
readonly CLUSTER_NODE_FILE="/${EJABBERD_HOME}/cluster-done"
readonly PYTHON_JINJA2="import os;
import sys;
import jinja2;
sys.stdout.write(
jinja2.Template
(sys.stdin.read()
).render(env=os.environ))"
# backward compatibility environment variables
set +e
[[ -n $EJABBERD_ADMIN ]] \
&& export EJABBERD_ADMINS=${EJABBERD_ADMIN}
[[ -n $AUTH_METHOD ]] \
&& export EJABBERD_AUTH_METHOD=${AUTH_METHOD}
[[ -n $SKIP_MODULES_UPDATE ]] \
&& export EJABBERD_SKIP_MODULES_UPDATE=${SKIP_MODULES_UPDATE}
[[ -n $ERL_OPTIONS ]] \
&& export ERLANG_OPTIONS=${ERL_OPTIONS}
[[ -n $SSLCERT_HOST ]] \
&& export EJABBERD_SSLCERT_HOST=${SSLCERT_HOST}
[[ -n $SSLCERT_EXAMPLE_COM ]] \
&& export EJABBERD_SSLCERT_EXAMPLE_COM=${SSLCERT_EXAMPLE_COM}
[[ -n $LOGLEVEL ]] \
&& export EJABBERD_LOGLEVEL=${LOGLEVEL}
[[ -n $EJABBERD_WEB_ADMIN_SSL ]] \
&& export EJABBERD_HTTPS=${EJABBERD_WEB_ADMIN_SSL}
set -e

View File

@ -1,66 +0,0 @@
is_set() {
local var=$1
[[ -n $var ]]
}
is_zero() {
local var=$1
[[ -z $var ]]
}
file_exist() {
local file=$1
[[ -e $file ]]
}
is_true() {
local var=${1,,}
local choices=("yes" "1" "y" "true")
for ((i=0;i < ${#choices[@]};i++)) {
[[ "${choices[i]}" == $var ]] && return 0
}
return 1
}
# overwrite this function to get hostname from other sources
# like dns or etcd
get_nodename() {
echo ${HOSTNAME}
}
join_cluster() {
local cluster_node=$1
is_zero ${cluster_node} \
&& exit 0
echo "Join cluster..."
local erlang_node_name=${ERLANG_NODE%@*}
local erlang_cluster_node="${erlang_node_name}@${cluster_node}"
response=$(${EJABBERDCTL} ping ${erlang_cluster_node})
while [ "$response" != "pong" ]; do
echo "Waiting for ${erlang_cluster_node}..."
sleep 2
response=$(${EJABBERDCTL} ping ${erlang_cluster_node})
done
echo "Join cluster at ${erlang_cluster_node}... "
NO_WARNINGS=true ${EJABBERDCTL} join_cluster $erlang_cluster_node
if [ $? -eq 0 ]; then
touch ${CLUSTER_NODE_FILE}
else
echo "cloud not join cluster"
exit 1
fi
}

View File

@ -1 +0,0 @@
# Overridable file

View File

@ -1 +0,0 @@
# Overridable file

View File

@ -1,24 +0,0 @@
#!/bin/bash
set -e
# Updates the known modules as to be found in https://github.com/processone/ejabberd-contrib
source "${EJABBERD_HOME}/scripts/lib/base_config.sh"
source "${EJABBERD_HOME}/scripts/lib/config.sh"
source "${EJABBERD_HOME}/scripts/lib/base_functions.sh"
source "${EJABBERD_HOME}/scripts/lib/functions.sh"
run_modules_update_specs() {
echo -n 'Updating module specs... '
${EJABBERDCTL} modules_update_specs
}
is_true ${EJABBERD_SKIP_MODULES_UPDATE} \
&& exit 0
run_modules_update_specs
exit 0

View File

@ -1,143 +0,0 @@
#!/bin/bash
set -e
# Installs modules as defined in environment variables
source "${EJABBERD_HOME}/scripts/lib/base_config.sh"
source "${EJABBERD_HOME}/scripts/lib/config.sh"
source "${EJABBERD_HOME}/scripts/lib/base_functions.sh"
source "${EJABBERD_HOME}/scripts/lib/functions.sh"
install_module_from_source() {
local module_name=$1
local module_source_path=${EJABBERD_HOME}/module_source/${module_name}
local module_install_folder=${EJABBERD_HOME}/.ejabberd-modules/sources
echo "Analyzing module ${module_name} for installation"
# Make sure that the module exists in the source folder before attempting a copy
if [ ! -d ${module_source_path} ]; then
echo "Error: Module ${module_name} not found in ${EJABBERD_HOME}/module_source"
echo "Please use a shared volume to populate your module in ${EJABBERD_HOME}/module_source"
return 1;
fi
# Check to see if the module is already installed
local install_count=$(${EJABBERDCTL} modules_installed | grep -ce "^${module_name}[[:space:]]")
if [ $install_count -gt 0 ]; then
echo "Error: Module already installed: ${module_name}"
return 1;
fi
# Copy the module into the shared folder
echo "Copying module to ejabberd folder ${module_install_folder}"
mkdir -p ${module_install_folder}
cp -R ${module_source_path} ${module_install_folder}
# Run the ejabberdctl module_check on the module
echo "Running module_check on ${module_name}"
${EJABBERDCTL} module_check ${module_name}
if [ $? -ne 0 ]; then
echo "Module check failed for ${module_name}"
return 1;
fi
echo "Module check succeeded for ${module_name}"
# Install the module
echo "Running module_install on ${module_name}"
${EJABBERDCTL} module_install ${module_name}
if [ $? -ne 0 ]; then
echo "Module installation failed for ${module_name}"
return 1;
fi
echo "Module installation succeeded for ${module_name}"
return 0;
}
install_module_from_ejabberd_contrib() {
local module_name=$1
# Check to see if the module is already installed
local install_count=$(${EJABBERDCTL} modules_installed | grep -ce "^${module_name}[[:space:]]")
if [ $install_count -gt 0 ]; then
echo "Error: Module already installed: ejabberd_contrib ${module_name}"
return 1;
fi
# Install the module
echo "Running module_install on ejabberd_contrib ${module_name}"
${EJABBERDCTL} module_install ${module_name}
if [ $? -ne 0 ]; then
echo "Module installation failed for ejabberd_contrib ${module_name}"
return 1;
fi
echo "Module installation succeeded for ejabberd_contrib ${module_name}"
return 0;
}
enable_custom_auth_module_override() {
module_name=$1;
# When using custom authentication modules, the module name must be
# in the following pattern: ejabberd_auth_foo, where foo is the
# value you will use for your auth_method yml configuration.
required_prefix="ejabberd_auth_"
if [[ "${module_name}" != "${required_prefix}"* ]]; then
echo "Error: module_name must begin with ${required_prefix}"
exit 1;
fi
echo "Checking custom auth module: ${module_name}"
# Make sure the auth module is installed
local install_count=$(${EJABBERDCTL} modules_installed | grep -ce "^${module_name}[[:space:]]")
if [ $install_count -eq 0 ]; then
echo "Error: custom auth_module not installed: ${module_name}"
return 1;
fi
custom_auth_method=${module_name#$required_prefix}
echo -e "\nauth_method: [${custom_auth_method}]" >> ${CONFIGFILE}
echo "Custom auth module ${module_name} configuration complete."
}
file_exist ${FIRST_START_DONE_FILE} \
&& exit 0
is_restart_needed=0;
if [ -n "${EJABBERD_SOURCE_MODULES}" ]; then
for module_name in ${EJABBERD_SOURCE_MODULES} ; do
install_module_from_source ${module_name}
done
is_restart_needed=1;
fi
# Check the EJABBERD_CONTRIB_MODULES variable for any ejabberd_contrib modules
if [ -n "${EJABBERD_CONTRIB_MODULES}" ]; then
for module_name in ${EJABBERD_CONTRIB_MODULES} ; do
install_module_from_ejabberd_contrib ${module_name}
done
is_restart_needed=1;
fi
# If a custom module was defined for handling auth, we need to override
# the pre-defined auth methods in the config.
if [ -n "${EJABBERD_CUSTOM_AUTH_MODULE_OVERRIDE}" ]; then
enable_custom_auth_module_override "${EJABBERD_CUSTOM_AUTH_MODULE_OVERRIDE}"
is_restart_needed=1;
fi
# If any modules were installed, restart the server, if the option is enabled
if [ ${is_restart_needed} -eq 1 ]; then
if is_true ${EJABBERD_RESTART_AFTER_MODULE_INSTALL} ; then
echo "Restarting ejabberd after successful module installation(s)"
${EJABBERDCTL} restart
child=$!
${EJABBERDCTL} "started"
wait $child
fi
fi
exit 0

View File

@ -1,118 +0,0 @@
#!/bin/bash
source "${EJABBERD_HOME}/scripts/lib/base_config.sh"
source "${EJABBERD_HOME}/scripts/lib/config.sh"
source "${EJABBERD_HOME}/scripts/lib/base_functions.sh"
source "${EJABBERD_HOME}/scripts/lib/functions.sh"
# Do not exit if users already registered
set +e
randpw() {
< /dev/urandom tr -dc A-Z-a-z-0-9 | head -c ${1:-16};
echo;
}
register_user() {
local user=$1
local domain=$2
local password=$3
${EJABBERDCTL} register ${user} ${domain} ${password}
return $?
}
register_all_users() {
# register users from environment $EJABBERD_USERS with given
# password or random password written to stout. Use whitespace
# to seperate users.
#
# sample:
# - add a user with an given password:
# -e "EJABBERD_USERS=admin@example.com:adminSecret"
# - add a user with a random password:
# -e "EJABBERD_USERS=user@example.com"
# - set password for admin and use random for user1:
# -e "EJABBERD_USERS=admin@example.com:adminSecret user@example.com"
for user in ${EJABBERD_USERS} ; do
local jid=${user%%:*}
local password=${user#*:}
local username=${jid%%@*}
local domain=${jid#*@}
[[ "${password}" == "${jid}" ]] \
&& password=$(randpw)
register_user ${username} ${domain} ${password}
local retval=$?
[[ ${retval} -eq 0 ]] \
&& echo "Password for user ${username}@${domain} is ${password}"
done
}
file_exist ${FIRST_START_DONE_FILE} \
&& exit 0
file_exist ${CLUSTER_NODE_FILE} \
&& exit 0
is_set ${EJABBERD_USERS} \
&& register_all_users
##################################
## Keep for backward compatibility
register_all_ejabberd_admins() {
# add all admins from environment $EJABBERD_ADMINS with the passwords from
# environment $EJABBERD_ADMIN_PASS.
local passwords
local IFS=' '
read -a passwords <<< "${EJABBERD_ADMIN_PWD}"
for admin in ${EJABBERD_ADMINS} ; do
local user=${admin%%@*}
local domain=${admin#*@}
local password=${passwords[0]}
passwords=("${passwords[@]:1}")
register_user ${user} ${domain} ${password}
done
}
register_all_ejabberd_admins_randpw() {
# add all admins from environment $EJABBERD_ADMINS with a random
# password and write the password to stdout.
for admin in ${EJABBERD_ADMINS} ; do
local user=${admin%%@*}
local domain=${admin#*@}
local password=$(randpw)
register_user ${user} ${domain} ${password}
local retval=$?
[[ ${retval} -eq 0 ]] \
&& echo "Password for user ${user}@${domain} is ${password}"
done
}
is_set ${EJABBERD_ADMIN_PWD} \
&& register_all_ejabberd_admins
is_true ${EJABBERD_ADMIN_RANDPWD} \
&& register_all_ejabberd_admins_randpw
exit 0

View File

@ -1,14 +0,0 @@
#!/bin/bash
set -e
# Write a first-start-done file
source "${EJABBERD_HOME}/scripts/lib/base_config.sh"
source "${EJABBERD_HOME}/scripts/lib/config.sh"
source "${EJABBERD_HOME}/scripts/lib/base_functions.sh"
source "${EJABBERD_HOME}/scripts/lib/functions.sh"
if [ ! -e "${FIRST_START_DONE_FILE}" ]; then
touch ${FIRST_START_DONE_FILE}
fi

View File

@ -1,23 +0,0 @@
#!/bin/bash
set -e
source "${EJABBERD_HOME}/scripts/lib/base_config.sh"
source "${EJABBERD_HOME}/scripts/lib/config.sh"
source "${EJABBERD_HOME}/scripts/lib/base_functions.sh"
source "${EJABBERD_HOME}/scripts/lib/functions.sh"
readonly whoami=$(whoami)
change_ejabberd_run_user() {
echo "Change ejabberd install user to root..."
sed -i "s/INSTALLUSER=${EJABBERD_USER}/INSTALLUSER=${whoami}/" ${EJABBERDCTL}
}
[[ "${whoami}" == "root" ]] \
&& change_ejabberd_run_user
exit 0

View File

@ -1,33 +0,0 @@
#!/bin/bash
set -e
source "${EJABBERD_HOME}/scripts/lib/base_config.sh"
source "${EJABBERD_HOME}/scripts/lib/config.sh"
source "${EJABBERD_HOME}/scripts/lib/base_functions.sh"
source "${EJABBERD_HOME}/scripts/lib/functions.sh"
# Instead of having to mount a direction, specify the ssl certs
# via environment variables:
# `EJABBERD_SSLCERT_HOST` and `EJABBERD_SSLCERT_{domain_name}`.
# For example: `EJABBERD_SSLCERT_EXAMPLE_COM`.
write_file_from_env() {
echo "Writing $1 to $2"
mkdir -p "$(dirname $2)"
echo "${!1}" > $2
}
# Write the host certificate
is_set ${EJABBERD_SSLCERT_HOST} \
&& write_file_from_env "EJABBERD_SSLCERT_HOST" ${SSLCERTHOST}
# Write the domain certificates for each XMPP_DOMAIN
for xmpp_domain in ${XMPP_DOMAIN} ; do
var="EJABBERD_SSLCERT_$(echo $xmpp_domain | awk '{print toupper($0)}' | sed 's/\./_/g;s/-/_/g')"
if is_set ${!var} ; then
file_exist "${SSLCERTDIR}/${xmpp_domain}.pem" \
|| write_file_from_env "$var" "${SSLCERTDIR}/${xmpp_domain}.pem"
fi
done
exit 0

View File

@ -1,91 +0,0 @@
#!/bin/bash
set -e
source "${EJABBERD_HOME}/scripts/lib/base_config.sh"
source "${EJABBERD_HOME}/scripts/lib/config.sh"
source "${EJABBERD_HOME}/scripts/lib/base_functions.sh"
source "${EJABBERD_HOME}/scripts/lib/functions.sh"
make_snakeoil_certificate() {
local domain=$1
local certfile=$2
openssl req -subj "/CN=${domain}" \
-new \
-newkey rsa:4096 \
-days 365 \
-nodes \
-x509 \
-keyout /tmp/selfsigned.key \
-out /tmp/selfsigned.crt
echo "Writing ssl cert and private key to '${certfile}'..."
cat /tmp/selfsigned.crt /tmp/selfsigned.key > ${certfile}
rm /tmp/selfsigned.crt /tmp/selfsigned.key
}
make_host_snakeoil_certificate() {
local IFS=@
local domain='localhost'
local erlang_node=${ERLANG_NODE}
if is_true ${erlang_node} ; then
domain=${HOSTNAME}
elif is_set ${erlang_node} ; then
set ${erlang_node}
local nodehost=$2
if is_zero ${nodehost} ; then
domain=${HOSTNAME}
else
domain=${nodehost}
fi
fi
echo -n "Missing ssl cert for your host. "
echo "Generating snakeoil ssl cert for ${domain}..."
make_snakeoil_certificate ${domain} ${SSLCERTHOST}
}
make_domain_snakeoil_certificate() {
local domain=$1
local certfile=$2
echo -n "Missing ssl cert for your xmpp domain. "
echo "Generating snakeoil ssl cert for ${domain}..."
make_snakeoil_certificate ${domain} ${certfile}
}
## backward compatibility
# link old xmpp_domain.pem file to the first <domainname>.pem in XMPP_DOMAIN
readonly SSLCERTDOMAIN="${SSLCERTDIR}/xmpp_domain.pem"
if file_exist ${SSLCERTDOMAIN} ; then
for xmpp_domain in ${XMPP_DOMAIN} ; do
file_exist "${SSLCERTDIR}/${xmpp_domain}.pem" \
|| ln -s ${SSLCERTDOMAIN} "${SSLCERTDIR}/${xmpp_domain}.pem"
break
done
fi
is_true ${EJABBERD_SKIP_MAKE_SSLCERT} \
&& echo "Skip certificate generation" \
&& exit 0
# generate host ssl cert if missing
file_exist ${SSLCERTHOST} \
|| make_host_snakeoil_certificate
# generate xmmp domain ssl certificates if missing
for xmpp_domain in ${XMPP_DOMAIN} ; do
domain_certfile="${SSLCERTDIR}/${xmpp_domain}.pem"
file_exist ${domain_certfile} \
|| make_domain_snakeoil_certificate ${xmpp_domain} ${domain_certfile}
done
exit 0

View File

@ -1,28 +0,0 @@
#!/bin/bash
set -e
source "${EJABBERD_HOME}/scripts/lib/base_config.sh"
source "${EJABBERD_HOME}/scripts/lib/config.sh"
source "${EJABBERD_HOME}/scripts/lib/base_functions.sh"
source "${EJABBERD_HOME}/scripts/lib/functions.sh"
make_dhparam() {
local dhfile=$1
local bits=$2
echo "Writing dh file to '${dhfile}'..."
openssl dhparam -out ${dhfile} ${bits}
}
is_true ${EJABBERD_SKIP_MAKE_DHPARAM} \
&& echo "Skip DH param generation" \
&& exit 0
if is_true ${EJABBERD_DHPARAM} ; then
file_exist ${SSLDHPARAM} \
|| make_dhparam ${SSLDHPARAM} 4096
fi
exit 0

View File

@ -1,25 +0,0 @@
#!/bin/bash
set -e
source "${EJABBERD_HOME}/scripts/lib/base_config.sh"
source "${EJABBERD_HOME}/scripts/lib/config.sh"
source "${EJABBERD_HOME}/scripts/lib/base_functions.sh"
source "${EJABBERD_HOME}/scripts/lib/functions.sh"
set_erlang_cookie() {
echo "Set erlang cookie to ${ERLANG_COOKIE}..."
echo ${ERLANG_COOKIE} > ${ERLANGCOOKIEFILE}
chmod 400 ${ERLANGCOOKIEFILE}
}
file_exist ${FIRST_START_DONE_FILE} \
&& exit 0
# set erlang cookie if ERLANG_COOKIE is set in environemt
is_set ${ERLANG_COOKIE} \
&& set_erlang_cookie
exit 0

View File

@ -1,38 +0,0 @@
#!/bin/bash
set -e
source "${EJABBERD_HOME}/scripts/lib/base_config.sh"
source "${EJABBERD_HOME}/scripts/lib/config.sh"
source "${EJABBERD_HOME}/scripts/lib/base_functions.sh"
source "${EJABBERD_HOME}/scripts/lib/functions.sh"
make_config() {
if [ ! -e ${CONFIGFILE} ]; then
echo "Generating ejabberd config file..."
cat ${CONFIGTEMPLATE} \
| python -c "${PYTHON_JINJA2}" \
> ${CONFIGFILE}
else
echo "ejabberd config file exists."
fi
if [ ! -e ${CTLCONFIGFILE} ]; then
echo "Generating ejabberdctl config file..."
cat ${CTLCONFIGTEMPLATE} \
| python -c "${PYTHON_JINJA2}" \
> ${CTLCONFIGFILE}
else
echo "ejabberdctl config file exists."
fi
}
file_exist ${FIRST_START_DONE_FILE} \
&& exit 0
# generate config file
make_config
exit 0

View File

@ -1,21 +0,0 @@
#!/bin/bash
set -e
source "${EJABBERD_HOME}/scripts/lib/base_config.sh"
source "${EJABBERD_HOME}/scripts/lib/config.sh"
source "${EJABBERD_HOME}/scripts/lib/base_functions.sh"
source "${EJABBERD_HOME}/scripts/lib/functions.sh"
leave_cluster() {
echo "Leave cluster... "
rm ${CLUSTER_NODE_FILE}
NO_WARNINGS=true ${EJABBERDCTL} leave_cluster
}
file_exist ${CLUSTER_NODE_FILE} \
&& leave_cluster
exit 0