Compare commits

...

56 commits
v1.0.0 ... dev

Author SHA1 Message Date
Sara Aimée Smiseth
113ca610ac
Update PROSODY_VERSION=0.12.5 (#73)
Some checks failed
Docker / buildx (push) Has been cancelled
Test / test (push) Has been cancelled
2025-01-05 15:22:58 +01:00
Sara Aimée Smiseth
4acb4b42a8
Update LUAROCKS_VERSION=3.11.1 (#72) 2024-11-19 15:41:10 +01:00
Sara Aimée Smiseth
982ddcd60b
Move defaults from entrypoint script to cfg.lua files (#71)
* Move multiple defaults from entrypoint script to cfg.lua files.

* Move remaining defaults from entrypoint script to cfg.lua files.

* Update postgres version in tests

* Register users with prosodyctl in tests

* Replace 'docker-compose' with 'docker compose'
2024-11-19 15:09:13 +01:00
Sara Aimée Smiseth
0e33f70739
Remove modules from Dockerfile which are already part of core modules (#66)
See https://prosody.im/doc/modules.

Add test to check if log contains warnings

This fixes https://github.com/SaraSmiseth/prosody/issues/63.
2024-03-04 17:46:15 +01:00
Sara Aimée Smiseth
74c64514e2
Remove broken links. (#65) 2024-02-20 19:43:58 +01:00
Sara Aimée Smiseth
d8e5906e55
Fix deprecated config options (#64)
Adjust config:
Replace deprecated legacy_ssl with c2s_direct_tls.
Removed use_libevent = true. This means the default is now used which is epoll.

Added a test to check that no deprecated config settings are used.
2024-02-20 18:52:34 +01:00
Sara Aimée Smiseth
fe1787f93c
Switched from [http_upload](https://modules.prosody.im/mod_http_upload) to [http_file_share](https://prosody.im/doc/modules/mod_http_file_share). (#60) 2023-09-14 20:02:00 +02:00
Sara Aimée Smiseth
f8d0fe4f59
Update prosody to version 0.12.4. (#59) 2023-09-09 20:29:13 +02:00
Sara Aimée Smiseth
da2f438bda
Add ENV variables for http_max_content_size and http_upload_file_size_limit (#57)
Fixes #55 and fixes #56:

* Add environment variable HTTP_UPLOAD_FILE_SIZE_LIMIT for setting http_upload_file_size_limit
* Add environment variable HTTP_MAX_CONTENT_SIZE
* Add domain_http_upload to disco_items to support http_upload on some clients and if http_upload is not a subdomain
2023-09-07 17:48:56 +02:00
Sara Aimée Smiseth
375b006814
Update to debian bookworm (#54) 2023-07-09 09:59:41 +02:00
Sara Aimée Smiseth
e6415fa513
Add tests for prosody with LDAP authentication (#53)
This commit updates the docker-compose.yml file to use example.com domain instead of localhost.

It also adds a new Prosody instance using LDAP authentication with glauth as the backend. The commit also includes a new file config.cfg for the glauth server configuration.
2023-03-28 08:08:01 +02:00
Sara Aimée Smiseth
81e9c1abd9
Add LDAP authentication support to Prosody (#50)
This commit adds support for LDAP authentication.

The Dockerfile has been modified to install the required Lua modules (lua-ldap) and the prosody.cfg.lua file has been modified to add environment variables for configuring the LDAP connection. These environment variables include LDAP_BASE, LDAP_SERVER, LDAP_ROOTDN, LDAP_PASSWORD, LDAP_FILTER, LDAP_SCOPE, LDAP_TLS, LDAP_MODE, and LDAP_ADMIN_FILTER.

The authentication variable has also been updated to use the value of the AUTHENTICATION environment variable, which defaults to "internal_hashed" if not set. This allows users to configure Prosody to use LDAP for authentication instead of the default internal hashing method.

* Update test dependencies: aioxmpp, pytest-asyncio + add pytz to requirements.txt

This fixes the following error when running the tests:
E   ModuleNotFoundError: No module named 'pytz'

Instead of pytz only pytz-deprecation-shim was installed.

TODO Check if "pytz" can be removed from requirements.txt later on.
2023-03-25 11:23:51 +01:00
Sara Aimée Smiseth
f7fcfd5d88
Update prosody and luarocks (#48)
* Update prosody to version 0.12.3.
* Update luarocks to version 3.9.2
2023-02-23 16:22:36 +01:00
Sara Aimée Smiseth
ab2afd4249
Update prosody to version 0.12.1 (#37) 2022-06-15 17:57:41 +02:00
Sara Aimée Smiseth
bd7a27ea74
Update bats-assert + bats-core + bats-support (#36) 2022-05-18 16:50:37 +02:00
Sara Aimée Smiseth
7a4ebd68d8
Update prosody to version 0.12.0 (#35)
* Update luarocks to 3.9.0
* Update tests for prosody version 0.12.0
2022-05-05 18:25:19 +02:00
Sara Aimée Smiseth
13d9c1b9d1
Update prosody to version 0.11.13 (#34) 2022-01-27 21:23:32 +01:00
Sara Aimée Smiseth
52e8f5388e
Update prosody to version 0.11.12 (#33) 2022-01-24 18:08:55 +01:00
Sara Aimée Smiseth
75e4b05ce5
Updates to luarocks and prosody (#32)
* Updated to Prosody version 0.11.11.
* Updated luarocks to version 3.8.0.
* .github workflow: Use actions/checkout@v2 with submodules: recursive
2021-12-23 16:01:53 +01:00
Sara Aimée Smiseth
eab04aeaf0
Update prosody to version 0.11.10 (#28) 2021-09-02 20:48:59 +02:00
Sara Aimée Smiseth
ca4e265ffe
Update debian from buster-slim to bullseye-slim (#27) 2021-08-05 10:15:53 +02:00
Sara Aimée Smiseth
4bbcdb80e9
Updated prosody to version 0.11.9 (#26)
Prepare version v1.2.1
2021-05-13 15:33:16 +02:00
Sara Aimée Smiseth
1966b38aac
Information about permissions (#25)
This fixes #3
2021-05-13 14:25:09 +02:00
Sara Aimée Smiseth
80216c5fdc
Add support for postgres, mariadb/mysql databases (#23)
* Add environment variables for Database configuration.
* Install postgres and mysql dependencies.
* Test refactoring
* Run tests for prosody with postgres and also for prosody with sqlite.
* Add tests that check if postgres or sqlite is used.
2021-05-07 14:06:29 +02:00
Sara Aimée Smiseth
5bcf0fd3d0
Update luarocks to version 3.7.0 (#22) 2021-04-17 13:32:49 +02:00
Sara Aimée Smiseth
aec0a30279
Updated luarocks to version 3.6.0 (#21)
* Update luarocks 3.6.0
2021-03-31 18:03:14 +02:00
Sara Aimée Smiseth
66723e19a1
Updated prosody to version 0.11.8 (#19) 2021-02-16 16:46:07 +01:00
Sara Aimée Smiseth
dbc63cc00f
Updated luarocks to version 3.5.0. (#18) 2020-12-11 08:15:36 +01:00
Sara Aimée Smiseth
39bd69d39c Prepare for version v1.1.3 2020-10-30 17:53:00 +01:00
Sara Aimée Smiseth
b70fcbd98e
Create tests (#15)
Created a tests folder which contains pytest and bats tests.
Pytest is used to login and send messages to other accounts.
Bats is used to check the log for debug messages.

This fixes #13.
2020-10-30 17:47:05 +01:00
Sara Aimée Smiseth
fc45a7bab1
Add opencontainers LABELs (#17)
See https://github.com/opencontainers/image-spec/blob/master/annotations.md
2020-10-14 11:49:30 +02:00
Sara Aimée Smiseth
d2915f77f3
More badges (#16)
version, Git repository size, Github open issues, Github open pull requests
2020-10-13 17:03:52 +02:00
Sara Aimée Smiseth
357f4d4040
Fix arrays with multiple values (#14)
* fix arrays
* Set pidfile in prosody.cfg.lua
2020-10-10 08:55:43 +02:00
Sara Aimée Smiseth
ade86ee812 CHANGELOG.md v1.1.2 2020-10-02 06:16:14 +02:00
Sara Aimée Smiseth
58f5d18987 update luarocks to version 3.4.0 2020-10-01 18:22:06 +02:00
Sara Aimée Smiseth
ceef3c335f update prosody to version 0.11.7 2020-10-01 17:50:58 +02:00
Sara Aimée Smiseth
1980cf0899 Cherry picked [commit](fa13a990a1) from [zipizap/prosody](https://github.com/zipizap/prosody) which fixes a bug with env-vars not beeing initialized. 2020-09-30 15:40:40 +02:00
Ubuntu
9645f521f8 fix bug with env-vars
env-vars should be defined before the if conditional branches, so that
in case they execute, there will be no errors about undefined env-vars
2020-09-30 15:37:25 +02:00
Sara Aimée Smiseth
606e63f20f Added E2E_POLICY_WHITELIST ENV variable to configure e2e_policy_whitelist. 2020-09-26 18:54:56 +02:00
Sara Aimée Smiseth
15b95e5822 Remove obsolete server_contact_info section. Use ENV variables instead. 2020-09-26 18:43:35 +02:00
Sara Aimée Smiseth
fb50f748ee Make 03-e2e-policy.cfg.lua configurable with ENV variables. 2020-09-18 20:04:52 +02:00
Sara Aimée Smiseth
fd21384bdf Make 04-server_contact_info.cfg.lua configurable with ENV variables. Fixes #4 2020-09-18 16:26:45 +02:00
Sara Aimée Smiseth
a5c6d5ecef update prosody to version 0.11.6 2020-09-09 17:56:16 +02:00
Sara Aimée Smiseth
dbb91cbe5b replace master with dev 2020-07-12 17:45:21 +02:00
Sara Aimée Smiseth
5a963e31a8 Update CHANGELOG.md for new release. 2020-07-08 18:29:48 +02:00
Sara Aimée Smiseth
772f26d468 Add link to official documentation on certificate permissions to README. Related to #3 2020-07-08 17:43:24 +02:00
Sara Aimée Smiseth
522e26c5ac Change global ssl section to http_upload and legacy_ssl sections. It is only needed there. 2020-07-08 17:42:42 +02:00
Sara Aimée Smiseth
d49e03b5c9 Enable announce and lastactivity modules 2020-06-28 10:18:32 +02:00
Sara Aimée Smiseth
5537365e36 Download modules, install modules and delete modules in one Docker RUN. 2020-06-27 19:54:16 +02:00
Sara Aimée Smiseth
476dbd06b8 Refactor module install scripts to remove duplicate code. Fixes #6. 2020-06-27 19:47:57 +02:00
Sara Aimée Smiseth
9e24592826 Download prosody-modules only once. 2020-06-27 19:22:55 +02:00
Sara Aimée Smiseth
2500028412 Add PROSODY_ADMINS to specify who is an administrator. Fixes #7 2020-06-26 17:34:24 +02:00
Sara Aimée Smiseth
20b7d7258d Add CHANGELOG.md with unreleased changes 2020-06-21 16:05:05 +02:00
Sara Aimée Smiseth
829ecbab5a Add badges to README. Fixes #5. 2020-06-21 13:43:20 +02:00
Sara Aimée Smiseth
bd4c48a575 update readme. fixes #2 2020-06-21 12:10:24 +02:00
Sara Aimée Smiseth
c9719fdde3
Update docker-publish.yml 2020-06-12 12:58:39 +02:00
34 changed files with 964 additions and 265 deletions

View file

@ -2,11 +2,11 @@ name: Docker
on:
schedule:
- cron: '0 1 * * *'
- cron: "0 1 * * *"
pull_request:
branches: master
branches: dev
push:
branches: master
branches: dev
tags:
- v*
@ -14,13 +14,11 @@ jobs:
# Build and push image to docker hub.
buildx:
runs-on: ubuntu-latest
if: github.event_name == 'push'
steps:
- uses: actions/checkout@v2
-
name: Prepare
- name: Prepare
id: prepare
run: |
DOCKER_IMAGE=sarasmiseth/prosody
@ -47,30 +45,25 @@ jobs:
id: buildx
uses: crazy-max/ghaction-docker-buildx@v3.1.0
-
name: Docker Buildx (build)
- name: Docker Buildx (build)
run: |
docker buildx build --output "type=image,push=false" ${{ steps.prepare.outputs.buildx_args }}
-
name: Docker Login
- name: Docker Login
if: success() && github.event_name != 'pull_request'
env:
DOCKER_USERNAME: ${{ secrets.DOCKER_USERNAME }}
DOCKER_PASSWORD: ${{ secrets.DOCKER_PASSWORD }}
run: |
echo "${DOCKER_PASSWORD}" | docker login --username "${DOCKER_USERNAME}" --password-stdin
-
name: Docker Buildx (push)
- name: Docker Buildx (push)
if: success() && github.event_name != 'pull_request'
run: |
docker buildx build --output "type=image,push=true" ${{ steps.prepare.outputs.buildx_args }}
-
name: Docker Check Manifest
- name: Docker Check Manifest
if: always() && github.event_name != 'pull_request'
run: |
docker run --rm mplatform/mquery ${{ steps.prepare.outputs.docker_image }}:${{ steps.prepare.outputs.version }}
-
name: Clear
- name: Clear
if: always() && github.event_name != 'pull_request'
run: |
rm -f ${HOME}/.docker/config.json

26
.github/workflows/test.yml vendored Normal file
View file

@ -0,0 +1,26 @@
name: Test
on:
pull_request:
branches: dev
push:
branches: dev
jobs:
test:
runs-on: ubuntu-latest
steps:
- name: Checkout repository and submodules
uses: actions/checkout@v2
with:
submodules: recursive
- name: install python3-venv
run: sudo apt-get install python3-venv
- name: build test image
run: docker build . -t prosody
- name: run tests
run: cd ./tests/ && ./test.bash

3
.gitignore vendored
View file

@ -1 +1,4 @@
data/*
tests/certs/
tests/venv/
tests/__pycache__/

9
.gitmodules vendored Normal file
View file

@ -0,0 +1,9 @@
[submodule "tests/bats/bats-support"]
path = tests/bats/bats-support
url = https://github.com/bats-core/bats-support.git
[submodule "tests/bats/bats-core"]
path = tests/bats/bats-core
url = https://github.com/bats-core/bats-core.git
[submodule "tests/bats/bats-assert"]
path = tests/bats/bats-assert
url = https://github.com/bats-core/bats-assert.git

153
CHANGELOG.md Normal file
View file

@ -0,0 +1,153 @@
# Changelog
## Unreleased
### Adjust config
* Replace deprecated legacy_ssl with c2s_direct_tls.
* Removed use_libevent = true. This means the default is now used which is epoll.
### Test
Added a test to check that no deprecated config settings are used.
## v1.3.0
* Updated to Prosody version [0.12.4](https://blog.prosody.im/prosody-0.12.4-released/)
### Breaking Change
Switched from [http_upload](https://modules.prosody.im/mod_http_upload) to [http_file_share](https://prosody.im/doc/modules/mod_http_file_share).
This means that previous uploads will NOT work after upgrading.
ENV variable `HTTP_UPLOAD_FILE_SIZE_LIMIT` was removed.
The new module uses the following variables:
* HTTP_FILE_SHARE_SIZE_LIMIT
* HTTP_FILE_SHARE_DAILY_QUOTA
See [readme.md](readme.md) for explanations and defaults.
## v1.2.10
* Update docker base image to debian bookworm
* [Add LDAP authentication support](https://github.com/SaraSmiseth/prosody/pull/50)
* Add environment variable HTTP_MAX_CONTENT_SIZE for setting http_max_content_size.
* Add environment variable HTTP_UPLOAD_FILE_SIZE_LIMIT for setting http_upload_file_size_limit.
* Add domain_http_upload to disco_items to support http_upload on some clients and if http_upload is not a subdomain.
## v1.2.9
* Update prosody to version 0.12.3
* Update luarocks to version 3.9.2
## v1.2.8
* Updated to Prosody version [0.12.1](https://blog.prosody.im/prosody-0.12.1-released/).
## v1.2.7
* Updated to Prosody version [0.12.0](https://blog.prosody.im/prosody-0.12.0-released/).
* Updated luarocks to version 3.9.0.
## v1.2.6
* Updated to Prosody version [0.11.13](https://blog.prosody.im/prosody-0.11.13-released/).
## v1.2.5
* Updated to Prosody version [0.11.12](https://blog.prosody.im/prosody-0.11.12-released/).
## v1.2.4
* Updated to Prosody version [0.11.11](https://blog.prosody.im/prosody-0.11.11-released/).
* Updated luarocks to version 3.8.0.
## v1.2.3
* Updated to Prosody version [0.11.10](https://blog.prosody.im/prosody-0.11.10-released/).
## v1.2.2
- Update debian from buster-slim to bullseye-slim (#27)
## v1.2.1
* Updated to Prosody version [0.11.9](https://blog.prosody.im/prosody-0.11.9-released/).
## v1.2.0
### New features
* New environment variables for database settings. It is now possible to use MariaDB or Postgres instead of SQLite. SQLite is the default. See [README](https://github.com/SaraSmiseth/prosody#environment-variables).
### Updates
* Updated luarocks to version 3.7.0.
## v1.1.4
### Updates
* Updated to Prosody version [0.11.8](https://blog.prosody.im/prosody-0.11.8-released/).
* Updated luarocks to version 3.5.0.
## v1.1.3
### New features
* Set pidfile in prosody.cfg.lua.
* Created a tests folder which contains pytest and bats tests.
### Bug fixes
* Fixed using list ENV variables with multiple values.
## v1.1.2
### Updates
* Updated to Prosody version [0.11.7](https://blog.prosody.im/prosody-0.11.7-released/).
* Updated luarocks to version 3.4.0.
### New features
* Made 04-server_contact_info.cfg.lua configurable with ENV variables. Fixes [#4](https://github.com/SaraSmiseth/prosody/issues/4).
* Made 03-e2e-policy.cfg.lua configurable with ENV variables. Fixes [#9](https://github.com/SaraSmiseth/prosody/issues/9).
* Added E2E_POLICY_WHITELIST ENV variable to configure e2e_policy_whitelist. Fixes [#10](https://github.com/SaraSmiseth/prosody/issues/10).
### Bug fixes
* Cherry picked [commit](https://github.com/zipizap/prosody/commit/fa13a990a1b87745ae5f5fe8297cb0669f9e8779) from [zipizap/prosody](https://github.com/zipizap/prosody) which fixes a bug with env-vars not beeing initialized.
### Other changes
* Changed hashing of downloaded packages in Dockerfile to sha256.
## v1.1.1
* Updated to Prosody version [0.11.6](https://blog.prosody.im/prosody-0.11.6-released/).
* Replace "master" with "dev".
## v1.1.0
### New features
* Enable "announce" and "lastactivity" modules.
* Add PROSODY_ADMINS to specify who is an administrator. Fixes #7
### Breaking changes
* Move global ssl section to https_ssl and legacy_ssl_ssl section. It is only needed there. #3
* <https://prosody.im/doc/ports#ssl_configuration>
As explained in the [README](https://github.com/SaraSmiseth/prosody#ssl-certificates) this setup uses automatic location to find your certs. This did not work correctly before this change. It just always used the main certificate defined with the global `ssl` config setting. This setting was removed and for the [services](https://prosody.im/doc/certificates#service_certificates) that do not use automatic location new global settings were introduced. These are `legacy_ssl_ssl` and `https_ssl`.
### Other changes
* Add badges to README. Fixes #5.
* Add link to official documentation on certificate permissions to README. Related to #3
## v1.0.0
* First version

View file

@ -1,32 +1,56 @@
FROM debian:buster-slim
FROM debian:bookworm-slim
ARG BUILD_DATE
ARG VCS_REF
ARG VERSION
ARG LUAROCKS_VERSION=3.11.1
ARG PROSODY_VERSION=0.12.5
ARG LUAROCKS_SHA256="c3fb3d960dffb2b2fe9de7e3cb004dc4d0b34bb3d342578af84f84325c669102"
ARG PROSODY_DOWNLOAD_SHA256="778fb7707a0f10399595ba7ab9c66dd2a2288c0ae3a7fe4ab78f97d462bd399f"
LABEL luarocks.version="${LUAROCKS_VERSION}"
LABEL org.opencontainers.image.authors="Sara Smiseth"
LABEL org.opencontainers.image.created="${BUILD_DATE}"
LABEL org.opencontainers.image.description="This docker image provides you with a configured Prosody XMPP server."
LABEL org.opencontainers.image.documentation="https://github.com/SaraSmiseth/prosody/blob/dev/readme.md"
LABEL org.opencontainers.image.revision="${VCS_REF}"
LABEL org.opencontainers.image.source="https://github.com/SaraSmiseth/prosody/archive/dev.zip"
LABEL org.opencontainers.image.title="prosody"
LABEL org.opencontainers.image.url="https://github.com/SaraSmiseth/prosody"
LABEL org.opencontainers.image.vendor="Sara Smiseth"
LABEL org.opencontainers.image.version="${VERSION}"
LABEL prosody.version="${PROSODY_VERSION}"
RUN apt-get update \
&& DEBIAN_FRONTEND=noninteractive apt-get install -y \
libevent-dev `# this is no build dependency, but needed for luaevent` \
libidn11 \
libicu72 \
libidn2-0 \
libpq-dev \
libsqlite3-0 \
lua5.2 \
lua-bitop \
lua-dbi-mysql \
lua-dbi-postgresql \
lua-expat \
lua-filesystem \
lua-ldap \
lua-socket \
lua-sec \
sqlite3 \
lua-unbound \
wget \
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/*
ENV PROSODY_VERSION 0.11.5
ENV PROSODY_DOWNLOAD_URL https://prosody.im/downloads/source/prosody-${PROSODY_VERSION}.tar.gz
ENV PROSODY_DOWNLOAD_SHA1 fbe27d3203671a6ecd5ba8233dc4c113fd76cd2e
ENV LUAROCKS_VERSION 3.3.1
RUN buildDeps='gcc git libc6-dev libidn11-dev liblua5.2-dev libsqlite3-dev libssl-dev make unzip' \
RUN buildDeps='gcc git libc6-dev libidn2-dev liblua5.2-dev libsqlite3-dev libssl-dev libicu-dev make unzip' \
&& set -x \
&& apt-get update && apt-get install -y $buildDeps --no-install-recommends \
&& rm -rf /var/lib/apt/lists/* \
\
&& wget -O prosody.tar.gz "${PROSODY_DOWNLOAD_URL}" \
&& echo "${PROSODY_DOWNLOAD_SHA1} *prosody.tar.gz" | sha1sum -c - \
&& wget -O prosody.tar.gz "https://prosody.im/downloads/source/prosody-${PROSODY_VERSION}.tar.gz" \
&& echo "${PROSODY_DOWNLOAD_SHA256} *prosody.tar.gz" | sha256sum -c - \
&& mkdir -p /usr/src/prosody \
&& tar -xzf prosody.tar.gz -C /usr/src/prosody --strip-components=1 \
&& rm prosody.tar.gz \
@ -38,6 +62,7 @@ RUN buildDeps='gcc git libc6-dev libidn11-dev liblua5.2-dev libsqlite3-dev libss
&& mkdir /usr/src/luarocks \
&& cd /usr/src/luarocks \
&& wget https://luarocks.org/releases/luarocks-${LUAROCKS_VERSION}.tar.gz \
&& echo "${LUAROCKS_SHA256} luarocks-${LUAROCKS_VERSION}.tar.gz" | sha256sum -c - \
&& tar zxpf luarocks-${LUAROCKS_VERSION}.tar.gz \
&& cd luarocks-${LUAROCKS_VERSION} \
&& ./configure \
@ -46,7 +71,9 @@ RUN buildDeps='gcc git libc6-dev libidn11-dev liblua5.2-dev libsqlite3-dev libss
\
&& luarocks install luaevent \
&& luarocks install luadbi \
`#&& luarocks install luadbi-mysql MYSQL_INCDIR=/usr/include/mariadb/` \
&& luarocks install luadbi-sqlite3 \
&& luarocks install stringy \
\
&& apt-get purge -y --auto-remove $buildDeps
@ -56,32 +83,31 @@ RUN groupadd -r prosody \
&& useradd -r -g prosody prosody \
&& chown prosody:prosody /usr/local/var/lib/prosody
RUN mkdir -p /var/run/prosody/ \
&& chown prosody:prosody /var/run/prosody/
# https://github.com/prosody/prosody-docker/issues/25
ENV __FLUSH_LOG yes
ENV __FLUSH_LOG=yes
VOLUME ["/usr/local/var/lib/prosody"]
COPY prosody.cfg.lua /usr/local/etc/prosody/prosody.cfg.lua
COPY docker-entrypoint.sh /entrypoint.sh
COPY docker-entrypoint.bash /entrypoint.bash
COPY conf.d/*.cfg.lua /usr/local/etc/prosody/conf.d/
COPY docker-prosody-module-* /usr/local/bin/
RUN docker-prosody-module-install \
bookmarks `# XEP-0411: Bookmarks Conversion` \
carbons `# message carbons (XEP-0280)` \
COPY *.bash /usr/local/bin/
RUN download-prosody-modules.bash \
&& docker-prosody-module-install.bash \
cloud_notify `# XEP-0357: Push Notifications` \
csi `# client state indication (XEP-0352)` \
e2e_policy `# require end-2-end encryption` \
filter_chatstates `# disable "X is typing" type messages` \
smacks `# stream management (XEP-0198)` \
throttle_presence `# presence throttling in CSI`
RUN docker-prosody-module-copy \
http_upload `# file sharing (XEP-0363)` \
vcard_muc `# XEP-0153: vCard-Based Avatar (MUC)`
throttle_presence `# presence throttling in CSI` \
vcard_muc `# XEP-0153: vCard-Based Avatar (MUC)` \
&& rm -rf "/usr/src/prosody-modules"
USER prosody
ENTRYPOINT ["/entrypoint.sh"]
ENTRYPOINT ["/entrypoint.bash"]
CMD ["prosody", "-F"]

View file

@ -37,12 +37,12 @@ modules_enabled = {
-- Other specific functionality
"posix"; -- POSIX functionality, sends server to background, enables syslog, etc.
--"groups"; -- Shared roster support
--"announce"; -- Send announcement to all online users
"announce"; -- Send announcement to all online users
--"welcome"; -- Welcome users who register accounts
--"watchregistrations"; -- Alert admins of registrations
--"motd"; -- Send a message to users when they log in
--"legacyauth"; -- Legacy authentication. Only used by some old clients and bots.
"lastactivity";
"server_contact_info"; -- This module lets you advertise various contact addresses for your XMPP service via XEP-0157.
};

View file

@ -1,7 +1,12 @@
default_storage = "sql"
sql = {
driver = "SQLite3";
database = "prosody.sqlite";
driver = os.getenv("DB_DRIVER") or "SQLite3";
database = os.getenv("DB_DATABASE") or "prosody.sqlite";
host = os.getenv("DB_HOST");
port = os.getenv("DB_PORT");
username = os.getenv("DB_USERNAME");
password = os.getenv("DB_PASSWORD");
}
-- make 0.10-distributed mod_mam use sql store
@ -15,3 +20,4 @@ storage = {
-- https://modules.prosody.im/mod_mam.html
archive_expires_after = "1y"
http_max_content_size = os.getenv("HTTP_MAX_CONTENT_SIZE") or 1024 * 1024 * 10 -- Default is 10MB

View file

@ -1,6 +1,11 @@
e2e_policy_chat = "required"
e2e_policy_muc = "required"
e2e_policy_whitelist = {}
local stringy = require "stringy"
e2e_policy_chat = os.getenv("E2E_POLICY_CHAT") or "required"
e2e_policy_muc = os.getenv("E2E_POLICY_MUC") or "required"
local whitelist = os.getenv("E2E_POLICY_WHITELIST") or ""
e2e_policy_whitelist = stringy.split(whitelist, ", ")
e2e_policy_message_optional_chat = "For security reasons, OMEMO, OTR or PGP encryption is STRONGLY recommended for conversations on this server."
e2e_policy_message_required_chat = "For security reasons, OMEMO, OTR or PGP encryption is required for conversations on this server."
e2e_policy_message_optional_muc = "For security reasons, OMEMO, OTR or PGP encryption is STRONGLY recommended for MUC on this server."

View file

@ -1,10 +1,18 @@
local stringy = require "stringy"
local domain = os.getenv("DOMAIN")
local abuse = os.getenv("SERVER_CONTACT_INFO_ABUSE") or "xmpp:abuse@" .. domain
local admin = os.getenv("SERVER_CONTACT_INFO_ADMIN") or "xmpp:admin@" .. domain
local feedback = os.getenv("SERVER_CONTACT_INFO_FEEDBACK") or "xmpp:feedback@" .. domain
local sales = os.getenv("SERVER_CONTACT_INFO_SALES") or "xmpp:sales@" .. domain
local security = os.getenv("SERVER_CONTACT_INFO_SECURITY") or "xmpp:security@" .. domain
local support = os.getenv("SERVER_CONTACT_INFO_SUPPORT") or "xmpp:support@" .. domain
contact_info = {
abuse = { "xmpp:abuse@" .. domain };
admin = { "xmpp:admin@" .. domain };
feedback = { "xmpp:feedback@" .. domain };
sales = { "xmpp:sales@" .. domain };
security = { "xmpp:security@" .. domain };
support = { "xmpp:support@" .. domain };
abuse = stringy.split(abuse, ", ");
admin = stringy.split(admin, ", ");
feedback = stringy.split(feedback, ", ");
sales = stringy.split(sales, ", ");
security = stringy.split(security, ", ");
support = stringy.split(support, ", ");
}

View file

@ -1,25 +1,35 @@
local domain = os.getenv("DOMAIN")
local domain_http_upload = os.getenv("DOMAIN_HTTP_UPLOAD")
local domain_muc = os.getenv("DOMAIN_MUC")
local domain_proxy = os.getenv("DOMAIN_PROXY")
local domain_pubsub = os.getenv("DOMAIN_PUBSUB")
-- This is a fallback just for http_upload because service certificates are searched differently
-- https://prosody.im/doc/certificates#service_certificates
ssl = {
certificate = "certs/" .. domain .. "/fullchain.pem";
key = "certs/" .. domain .. "/privkey.pem";
}
local domain_http_upload = os.getenv("DOMAIN_HTTP_UPLOAD") or "upload." .. domain
local domain_muc = os.getenv("DOMAIN_MUC") or "conference." .. domain
local domain_proxy = os.getenv("DOMAIN_PROXY") or "proxy." .. domain
local domain_pubsub = os.getenv("DOMAIN_PUBSUB") or "pubsub." .. domain
-- XEP-0368: SRV records for XMPP over TLS
-- https://compliance.conversations.im/test/xep0368/
legacy_ssl_ports = { 5223 }
c2s_direct_tls_ssl = {
certificate = "certs/" .. domain .. "/fullchain.pem";
key = "certs/" .. domain .. "/privkey.pem";
}
c2s_direct_tls_ports = { 5223 }
-- https://prosody.im/doc/certificates#service_certificates
-- https://prosody.im/doc/ports#ssl_configuration
https_ssl = {
certificate = "certs/" .. domain_http_upload .. "/fullchain.pem";
key = "certs/" .. domain_http_upload .. "/privkey.pem";
}
VirtualHost (domain)
disco_items = {
{ domain_http_upload },
}
-- Set up a http file upload because proxy65 is not working in muc
Component (domain_http_upload) "http_upload"
http_upload_expire_after = 60 * 60 * 24 * 7 -- a week in seconds
Component (domain_http_upload) "http_file_share"
http_file_share_expires_after = 60 * 60 * 24 * 7 -- a week in seconds
local size_limit = os.getenv("HTTP_FILE_SHARE_SIZE_LIMIT") or 10 * 1024 * 1024 -- Default is 10MB
http_file_share_size_limit = size_limit
http_file_share_daily_quota = os.getenv("HTTP_FILE_SHARE_DAILY_QUOTA") or 10 * size_limit -- Default is 10x the size limit
Component (domain_muc) "muc"
name = "Prosody Chatrooms"

View file

18
docker-entrypoint.bash Executable file
View file

@ -0,0 +1,18 @@
#!/bin/bash
set -e
if [[ "$1" != "prosody" ]]; then
exec prosodyctl $*
exit 0;
fi
if [ "$LOCAL" -a "$PASSWORD" -a "$DOMAIN" ] ; then
prosodyctl register $LOCAL $DOMAIN $PASSWORD
fi
if [ -z "$DOMAIN" ]; then
echo "[ERROR] DOMAIN must be set!"
exit 1
fi
exec "$@"

View file

@ -1,28 +0,0 @@
#!/bin/bash
set -e
if [[ "$1" != "prosody" ]]; then
exec prosodyctl $*
exit 0;
fi
if [ "$LOCAL" -a "$PASSWORD" -a "$DOMAIN" ] ; then
prosodyctl register $LOCAL $DOMAIN $PASSWORD
fi
if [ -z "$DOMAIN" ]; then
echo "[ERROR] DOMAIN must be set!"
exit 1
fi
export ALLOW_REGISTRATION=${ALLOW_REGISTRATION:-true}
export DOMAIN_HTTP_UPLOAD=${DOMAIN_HTTP_UPLOAD:-"upload.$DOMAIN"}
export DOMAIN_MUC=${DOMAIN_MUC:-"conference.$DOMAIN"}
export DOMAIN_PROXY=${DOMAIN_PROXY:-"proxy.$DOMAIN"}
export DOMAIN_PUBSUB=${DOMAIN_PUBSUB:-"pubsub.$DOMAIN"}
export LOG_LEVEL=${LOG_LEVEL:-"info"}
export C2S_REQUIRE_ENCRYPTION=${C2S_REQUIRE_ENCRYPTION:-true}
export S2S_REQUIRE_ENCRYPTION=${S2S_REQUIRE_ENCRYPTION:-true}
export S2S_SECURE_AUTH=${S2S_SECURE_AUTH:-true}
exec "$@"

View file

@ -1,60 +0,0 @@
#!/bin/sh
set -e
source="/usr/src/prosody-modules"
target="/usr/local/lib/prosody/custom-modules"
config="/usr/local/etc/prosody/conf.d/01-modules.cfg.lua"
srcExists=
if [ -d ${source} ]; then
srcExists=1
fi
docker-prosody-module-source pullTo ${source}
if [ -z "$srcExists" ]; then
touch ${source}/.docker-delete-me
fi
cd ${source}
usage() {
echo "usage: $0 ext-name [ext-name ...]"
echo " ie: $0 carbons e2e_policy proxy65"
echo
echo 'Possible values for ext-name:'
find . -mindepth 1 -maxdepth 1 -type d | sort | sed s/\.\\/mod_//g | xargs
}
exts=
for ext; do
if [ -z "mod_$ext" ]; then
continue
fi
if [ ! -d "mod_$ext" ]; then
echo >&2 "error: $PWD/mod_$ext does not exist"
echo >&2
usage >&2
exit 1
fi
exts="$exts $ext"
done
if [ -z "$exts" ]; then
usage >&2
exit 1
fi
for ext in $exts; do
echo "Installing mod_${ext}"
echo " - copying to ${target}"
cp -r "${source}/mod_${ext}" "${target}/"
echo " - enabling within ${config}"
new_config=$(cat "${config}" | module="${ext}" perl -0pe 's/(modules_enabled[ ]*=[ ]*{[^}]*)};/$1\n\t"$ENV{module}";\n};/')
echo "${new_config}" > "${config}"
done
if [ -e ${source}/.docker-delete-me ]; then
docker-prosody-module-source deleteFrom ${source}
fi

View file

@ -1,18 +1,9 @@
#!/bin/sh
#!/bin/bash
set -e
source="/usr/src/prosody-modules"
target="/usr/local/lib/prosody/custom-modules"
srcExists=
if [ -d ${source} ]; then
srcExists=1
fi
docker-prosody-module-source pullTo ${source}
if [ -z "$srcExists" ]; then
touch ${source}/.docker-delete-me
fi
config="/usr/local/etc/prosody/conf.d/01-modules.cfg.lua"
cd ${source}
@ -48,8 +39,11 @@ for ext in $exts; do
echo " - copying to ${target}"
cp -r "${source}/mod_${ext}" "${target}/"
done
if [ -e ${source}/.docker-delete-me ]; then
docker-prosody-module-source deleteFrom ${source}
fi
# Skip this if the modules should not be added to modules_enabled.
if [ "$ext" != "http_upload" ] && [ "$ext" != "vcard_muc" ] ; then
echo " - enabling within ${config}"
new_config=$(cat "${config}" | module="${ext}" perl -0pe 's/(modules_enabled[ ]*=[ ]*{[^}]*)};/$1\n\t"$ENV{module}";\n};/')
echo "${new_config}" > "${config}"
fi
done

View file

@ -1,39 +0,0 @@
#!/bin/sh
set -e
dir=$2
usage() {
echo "usage: $0 COMMAND DIR"
echo
echo "Manage prosody-modules source lifecycle."
echo
echo "Commands:"
echo " pullTo extract prosody-module sources into directory ${dir} if not already done."
echo " deleteFrom delete extracted prosody-module sources located into ${dir} if not already done."
echo
}
case "$1" in
pullTo)
mkdir -p "${dir}"
if [ ! -f "${dir}/.docker-pulled" ]; then
wget https://hg.prosody.im/prosody-modules/archive/tip.tar.gz
tar -xzf tip.tar.gz -C "${dir}" --strip-components=1
rm tip.tar.gz
touch "${dir}/.docker-pulled"
fi
;;
deleteFrom)
rm -rf "${dir}"
;;
*)
usage
exit 1
;;
esac

9
download-prosody-modules.bash Executable file
View file

@ -0,0 +1,9 @@
#!/bin/bash
set -e
dir="/usr/src/prosody-modules"
mkdir -p "${dir}"
wget https://hg.prosody.im/prosody-modules/archive/tip.tar.gz
tar -xzf tip.tar.gz -C "${dir}" --strip-components=1
rm tip.tar.gz

View file

@ -1,20 +1,33 @@
-- see example config at https://hg.prosody.im/0.9/file/0.9.10/prosody.cfg.lua.dist
-- easily extendable by putting into different config files within conf.d folder
admins = {};
local stringy = require "stringy"
use_libevent = true; -- improves performance
local prosody_admins = os.getenv("PROSODY_ADMINS") or "";
admins = stringy.split(prosody_admins, ", ");
allow_registration = os.getenv("ALLOW_REGISTRATION");
pidfile = "/var/run/prosody/prosody.pid"
c2s_require_encryption = os.getenv("C2S_REQUIRE_ENCRYPTION");
s2s_require_encryption = os.getenv("S2S_REQUIRE_ENCRYPTION");
s2s_secure_auth = os.getenv("S2S_SECURE_AUTH");
allow_registration = os.getenv("ALLOW_REGISTRATION") or "true";
authentication = "internal_hashed";
c2s_require_encryption = os.getenv("C2S_REQUIRE_ENCRYPTION") or "true";
s2s_require_encryption = os.getenv("S2S_REQUIRE_ENCRYPTION") or "true";
s2s_secure_auth = os.getenv("S2S_SECURE_AUTH") or "true";
authentication = os.getenv("AUTHENTICATION") or "internal_hashed";
ldap_base = os.getenv("LDAP_BASE");
ldap_server = os.getenv("LDAP_SERVER") or "localhost";
ldap_rootdn = os.getenv("LDAP_ROOTDN") or "";
ldap_password = os.getenv("LDAP_PASSWORD") or "";
ldap_filter = os.getenv("LDAP_FILTER") or "(uid=$user)";
ldap_scope = os.getenv("LDAP_SCOPE") or "subtree";
ldap_tls = os.getenv("LDAP_TLS") or "false";
ldap_mode = os.getenv("LDAP_MODE") or "bind";
ldap_admin_filter = os.getenv("LDAP_ADMIN_FILTER") or "";
log = {
{levels = {min = os.getenv("LOG_LEVEL")}, to = "console"};
{levels = {min = os.getenv("LOG_LEVEL") or "info"}, to = "console"};
};
Include "conf.d/*.cfg.lua";

109
readme.md
View file

@ -1,7 +1,15 @@
# Prosody XMPP server for Raspberry Pi
# Prosody XMPP Docker image
This docker image provides you with a configured [Prosody](https://prosody.im/) XMPP server. The image is intended to run on a Raspberry Pi (as it is based on _balenalib/rpi-raspbian_).
![Docker](https://github.com/SaraSmiseth/prosody/workflows/Docker/badge.svg?branch=dev)
![Git repository size](https://img.shields.io/github/repo-size/SaraSmiseth/prosody)
[![Docker pulls](https://img.shields.io/docker/pulls/sarasmiseth/prosody.svg)](https://hub.docker.com/r/sarasmiseth/prosody/)
[![Docker stars](https://img.shields.io/docker/stars/sarasmiseth/prosody.svg)](https://hub.docker.com/r/sarasmiseth/prosody/)
[![Github open issues](https://img.shields.io/github/issues-raw/SaraSmiseth/prosody)](https://github.com/SaraSmiseth/prosody/issues)
[![Github open pull requests](https://img.shields.io/github/issues-pr-raw/SaraSmiseth/prosody)](https://github.com/SaraSmiseth/prosody/pulls)
This docker image provides you with a configured [Prosody](https://prosody.im/) XMPP server. The image is based on `debian:bookworm-slim`.
The server was tested using the Android App [Conversations](https://conversations.im/) and the Desktop client [Gajim](https://gajim.org).
Multiple [architectures](https://hub.docker.com/r/sarasmiseth/prosody/tags) are supported. I use it on my raspberry pi 4.
While Conversations got everything set-up out-of-the-box, Gajim was used with the following extensions:
@ -12,7 +20,7 @@ While Conversations got everything set-up out-of-the-box, Gajim was used with th
## Table of Contents
- [Prosody XMPP server for Raspberry Pi](#prosody-xmpp-server-for-raspberry-pi)
- [Prosody XMPP Docker image](#prosody-xmpp-docker-image)
- [Table of Contents](#table-of-contents)
- [Features](#features)
- [Requirements](#requirements)
@ -28,10 +36,11 @@ While Conversations got everything set-up out-of-the-box, Gajim was used with th
- [Symlinks](#symlinks)
- [Permissions](#permissions)
- [Run](#run)
- [Volumes permissions](#volumes-permissions)
- [Docker tags](#docker-tags)
- [Configuration](#configuration)
- [Environment variables](#environment-variables)
- [DNS](#dns)
- [server_contact_info](#server_contact_info)
- [Extend](#extend)
- [Upgrade](#upgrade)
- [Test your server](#test-your-server)
@ -44,13 +53,11 @@ While Conversations got everything set-up out-of-the-box, Gajim was used with th
* Data storage
* SQLite message store
* Configured file upload and image sharing
* Allows registration
* Multi-user chats
* Multi-user chat (MUC)
## Requirements
* You need a SSL certificate. I recommend [LetsEncrypt](https://letsencrypt.org/) for that.
* Your Raspberry Pi should have docker set-up and running. You could use the Raspberry image for [Hypriot OS](http://blog.hypriot.com/downloads/) to get started quickly.
## Image Details
@ -97,11 +104,9 @@ Path: ```/usr/local/etc/prosody/certs/```.
Uses [automatic location](https://prosody.im/doc/certificates#automatic_location) to find your certs.
The http_upload module does not use the same search algorithm for the certificates. See [service certificates](https://prosody.im/doc/certificates#service_certificates).
The http_upload module and the legacy_ssl module do not use the same search algorithm for the certificates. See [service certificates](https://prosody.im/doc/certificates#service_certificates).
The setting ssl in [05-vhost.cfg.lua](./conf.d/05-vhost.cfg.lua) configures certificates globally as a fallback.
Which defaults to ```cert/domain.tld/fullchain.pem``` and ```cert/domain.tld/privkey.pem```.
The settings https_ssl and legacy_ssl_ssl in [05-vhost.cfg.lua](./conf.d/05-vhost.cfg.lua) configures the certificates to ```certs/domain.tld/fullchain.pem``` and ```certs/domain.tld/privkey.pem``` for legacy_ssl and to ```certs/DOMAIN_HTTP_UPLOAD/fullchain.pem``` and ```certs/DOMAIN_HTTP_UPLOAD/privkey.pem``` for http_upload where DOMAIN_HTTP_UPLOAD is an environtment variable.
##### Folder structure
@ -135,18 +140,20 @@ For example ```cp -L src dest```.
##### Permissions
TODO
See official [documentation](https://prosody.im/doc/certificates#permissions) for more information.
Check [Volumes permissions](#volumes-permissions) as well.
### Run
I recommend using a ```docker-compose.yml``` file:
```yaml
version: '2'
version: '3.7'
services:
server:
image: shaula/rpi-prosody:0.10
image: sarasmiseth/prosody:latest
restart: unless-stopped
ports:
- "5000:5000"
- "5222:5222"
@ -158,29 +165,77 @@ services:
volumes:
- ./certs:/usr/local/etc/prosody/certs
- ./data:/usr/local/var/lib/prosody
restart: unless-stopped
```
Boot it via: ```docker-compose up -d```.
Boot it via: ```docker compose up -d```.
Inspect logs: ```docker-compose logs -f```.
Inspect logs: ```docker compose logs -f```.
### Volumes permissions
The prosody user inside the container has the `uid=999` and `gid=999`. If you use the example `docker-compose.yml` from above make sure, that the `./data` folder and the `./certs` folder have the correct permissions.
``` shell
sudo chown 999:999 ./certs
sudo chown 999:999 ./data
```
### Docker tags
<https://hub.docker.com/r/sarasmiseth/prosody/tags>
| Tag | Description |
| -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| edge | This tag points to the latest version build from the newest [commit](https://github.com/SaraSmiseth/prosody/commits/dev) in the dev branch. |
| nightly | This tag points to the latest version build from the newest [commit](https://github.com/SaraSmiseth/prosody/commits/dev) in the dev branch. It gets rebuild every night. |
| latest | This tag points to the latest version build from the latest commit that is tagged in git. See [releases](https://github.com/SaraSmiseth/prosody/releases). |
| *vX.Y.Z* | There is a tag for each [release](https://github.com/SaraSmiseth/prosody/releases). |
### Configuration
#### Environment variables
| Variable | Description | Type | Default value |
| -------------------------- | ------------------------------------------------------------------------------------------------------- | ------------ | --------------------- |
| -------------------------------- | -------------------------------------------------------------------------------------------------------------------- | -------------------------------------------- | -------------------------- |
| **ALLOW_REGISTRATION** | Whether to allow registration of new accounts via Jabber clients | *optional* | true |
| **DOMAIN** | domain | **required** | null |
| **DOMAIN_HTTP_UPLOAD** | Domain which lets clients upload files over HTTP | *optional* | upload.**DOMAIN** |
| **DOMAIN_MUC** | Domain for Multi-user chat (MUC) for allowing you to create hosted chatrooms/conferences for XMPP users | *optional* | conference.**DOMAIN** |
| **DOMAIN_PROXY** | Domain for SOCKS5 bytestream proxy for server-proxied file transfers | *optional* | proxy.**DOMAIN** |
| **DOMAIN_PUBSUB** | Domain for a XEP-0060 pubsub service | *optional* | pubsub.**DOMAIN** |
| **AUTHENTICATION** | authentication | *optional* | "internal_hashed" |
| **LDAP_BASE** | LDAP base directory which stores user accounts | **required** if **AUTHENTICATION** is "ldap" | |
| **LDAP_SERVER** | Space-separated list of hostnames or IPs, optionally with port numbers (e.g. “localhost:8389”) | *optional* | "localhost" |
| **LDAP_ROOTDN** | The distinguished name to auth against | *optional* | "" |
| **LDAP_PASSWORD** | Password for rootdn | *optional* | "" |
| **LDAP_FILTER** | Search filter, with $user and $host substituted for user- and hostname | *optional* | "(uid=$user)" |
| **LDAP_SCOPE** | Search scope. other values: “base” and “onelevel” | *optional* | "subtree" |
| **LDAP_TLS** | Enable TLS (StartTLS) to connect to LDAP (can be true or false). The non-standard LDAPS protocol is not supported. | *optional* | "false" |
| **LDAP_MODE** | How passwords are validated. | *optional* | "bind" |
| **LDAP_ADMIN_FILTER** | Search filter to match admins, works like ldap_filter | *optional* | "" |
| **DB_DRIVER** | May also be "PostgreSQL" or "MySQL" or "SQLite3" (case sensitive!) | *optional* | SQLite3 |
| **DB_DATABASE** | The database name to use. For SQLite3 this the database filename (relative to the data storage directory). | *optional* | prosody.sqlite |
| **DB_HOST** | The address of the database server | *optional* | |
| **DB_PORT** | Port on which the database is listening | *optional* | |
| **DB_USERNAME** | The username to authenticate to the database | *optional* | |
| **DB_PASSWORD** | The password to authenticate to the database | *optional* | |
| **HTTP_MAX_CONTENT_SIZE** | Max http content size in bytes | *optional* | 10485760 |
| **HTTP_FILE_SHARE_SIZE_LIMIT** | Max http file share size in bytes | *optional* | 10485760 |
| **HTTP_FILE_SHARE_DAILY_QUOTA** | Daily quota in bytes | *optional* | 10 times share size limit |
| **E2E_POLICY_CHAT** | Policy for chat messages. Possible values: "none", "optional" and "required". | *optional* | "required" |
| **E2E_POLICY_MUC** | Policy for MUC messages. Possible values: "none", "optional" and "required". | *optional* | "required" |
| **E2E_POLICY_WHITELIST** | Make this module ignore messages sent to and from this JIDs or MUCs. | *optional* | "" |
| **LOG_LEVEL** | Min log level. Change to debug for more information | *optional* | info |
| **C2S_REQUIRE_ENCRYPTION** | Whether to force all client-to-server connections to be encrypted or not | *optional* | true |
| **S2S_REQUIRE_ENCRYPTION** | Whether to force all server-to-server connections to be encrypted or not | *optional* | true |
| **S2S_SECURE_AUTH** | Require encryption and certificate authentication | *optional* | true |
| **SERVER_CONTACT_INFO_ABUSE** | A list of strings. Each string should be an URI. See [here](https://prosody.im/doc/modules/mod_server_contact_info). | *optional* | "xmpp:abuse@**DOMAIN**" |
| **SERVER_CONTACT_INFO_ADMIN** | A list of strings. Each string should be an URI. See [here](https://prosody.im/doc/modules/mod_server_contact_info). | *optional* | "xmpp:admin@**DOMAIN**" |
| **SERVER_CONTACT_INFO_FEEDBACK** | A list of strings. Each string should be an URI. See [here](https://prosody.im/doc/modules/mod_server_contact_info). | *optional* | "xmpp:feedback@**DOMAIN**" |
| **SERVER_CONTACT_INFO_SALES** | A list of strings. Each string should be an URI. See [here](https://prosody.im/doc/modules/mod_server_contact_info). | *optional* | "xmpp:sales@**DOMAIN**" |
| **SERVER_CONTACT_INFO_SECURITY** | A list of strings. Each string should be an URI. See [here](https://prosody.im/doc/modules/mod_server_contact_info). | *optional* | "xmpp:security@**DOMAIN**" |
| **SERVER_CONTACT_INFO_SUPPORT** | A list of strings. Each string should be an URI. See [here](https://prosody.im/doc/modules/mod_server_contact_info). | *optional* | "xmpp:support@**DOMAIN**" |
| **PROSODY_ADMINS** | Specify who is an administrator. List of adresses. Eg. "me@example.com", "admin@example.net" | *optional* | "" |
#### DNS
@ -195,20 +250,6 @@ You need these DNS record pointing to your server:
where domain.tld is the environment variable DOMAIN.
#### server_contact_info
This module lets you advertise various contact addresses for your XMPP service via XEP-0157.
It is configured for the following contacts:
* abuse
* admin
* feedback
* sales
* security
* support
You can change them in [05-server_contact_info.cfg.lua](./conf.d/04-server_contact_info.cfg.lua).
### Extend
There is a helper script that eases installing additional prosody modules: ```docker-prosody-module-install```
@ -221,10 +262,10 @@ If you need additional configuration just overwrite the respective _cfg.lua_ fil
### Upgrade
When migrating from 0.10, you need to update the database once:
When migrating from prosody 0.10, you need to update the database once:
```bash
docker-compose exec server bash
docker compose exec server bash
prosodyctl mod_storage_sql upgrade
```

@ -0,0 +1 @@
Subproject commit 397c735212bf1a06cfdd0cb7806c5a6ea79582bf

1
tests/bats/bats-core Submodule

@ -0,0 +1 @@
Subproject commit 410dd229a5ed005c68167cc90ed0712ad2a1c909

@ -0,0 +1 @@
Subproject commit 3c8fadc5097c9acfc96d836dced2bb598e48b009

80
tests/docker-compose.yml Normal file
View file

@ -0,0 +1,80 @@
services:
prosody:
image: prosody
restart: unless-stopped
ports:
- "5000:5000"
- "5222:5222"
- "5223:5223"
- "5269:5269"
- "5281:5281"
environment:
DOMAIN: example.com
E2E_POLICY_WHITELIST: "admin@example.com, user1@example.com"
LOG_LEVEL: debug
PROSODY_ADMINS: "admin@example.com, admin2@example.com"
volumes:
- ./certs:/usr/local/etc/prosody/certs
prosody_postgres:
image: prosody
restart: unless-stopped
ports:
- "5000:5000"
- "5222:5222"
- "5223:5223"
- "5269:5269"
- "5281:5281"
environment:
DOMAIN: example.com
E2E_POLICY_WHITELIST: "admin@example.com, user1@example.com"
LOG_LEVEL: debug
PROSODY_ADMINS: "admin@example.com, admin2@example.com"
#DB_DRIVER: "MySQL"
DB_DRIVER: "PostgreSQL"
DB_DATABASE: "prosody"
DB_HOST: "postgres"
DB_PORT: "5432"
DB_USERNAME: "prosody"
DB_PASSWORD: "prosody"
volumes:
- ./certs:/usr/local/etc/prosody/certs
depends_on:
- postgres
postgres:
image: postgres:16-alpine
restart: unless-stopped
environment:
POSTGRES_DB: prosody
POSTGRES_USER: prosody
POSTGRES_PASSWORD: prosody
prosody_ldap:
image: prosody
restart: unless-stopped
ports:
- "5000:5000"
- "5222:5222"
- "5223:5223"
- "5269:5269"
- "5281:5281"
environment:
DOMAIN: example.com
E2E_POLICY_WHITELIST: "admin@example.com, user1@example.com"
LOG_LEVEL: debug
PROSODY_ADMINS: "admin@example.com, admin2@example.com"
AUTHENTICATION: "ldap"
LDAP_BASE: "dc=example,dc=com"
LDAP_SERVER: "glauth"
LDAP_ROOTDN: "cn=svc,dc=example,dc=com"
LDAP_PASSWORD: "12345678"
volumes:
- ./certs:/usr/local/etc/prosody/certs
depends_on:
- glauth
glauth:
image: glauth/glauth
volumes:
- "./glauth/config.cfg:/app/config/config.cfg"

52
tests/glauth/config.cfg Normal file
View file

@ -0,0 +1,52 @@
[ldap]
enabled = true
listen = "0.0.0.0:389"
[ldaps]
enabled = false
[backend]
datastore = "config"
baseDN = "dc=example,dc=com"
[[groups]]
name = "svc"
gidnumber = 5500
[[groups]]
name = "people"
gidnumber = 5501
[[users]]
name = "svc"
uidnumber = 5000
primarygroup = 5500
passsha256 = "ef797c8118f02dfb649607dd5d3f8c7623048c9c063d532cc95c5ed7a898a64f"
[[users.capabilities]]
action = "search"
object = "*"
[[users]]
name = "admin"
uidnumber = 5001
primarygroup = 5501
passsha256 = "ef797c8118f02dfb649607dd5d3f8c7623048c9c063d532cc95c5ed7a898a64f"
[[users]]
name = "user1"
uidnumber = 5002
primarygroup = 5501
passsha256 = "ef797c8118f02dfb649607dd5d3f8c7623048c9c063d532cc95c5ed7a898a64f"
[[users]]
name = "user2"
uidnumber = 5003
primarygroup = 5501
passsha256 = "ef797c8118f02dfb649607dd5d3f8c7623048c9c063d532cc95c5ed7a898a64f"
[[users]]
name = "user3"
uidnumber = 5004
primarygroup = 5501
passsha256 = "ef797c8118f02dfb649607dd5d3f8c7623048c9c063d532cc95c5ed7a898a64f"

28
tests/readme.md Normal file
View file

@ -0,0 +1,28 @@
# Tests
Pytest is used to login and send messages to other accounts.
Bats is used to check the log for debug messages.
## Dependencies
* docker
* docker-compose
* python 3
## Run tests
Execute [`test.bash`](test.bash).
## Upgrade python packages
The following will install the newest version of packages in requirements.txt.
``` bash
cat requirements.txt | sed 's/==.*//g' | xargs pip install -U
```
If updates are available --> update and create new version with:
``` bash
pip-chill > requirements.txt
```

4
tests/requirements.txt Normal file
View file

@ -0,0 +1,4 @@
aioxmpp==0.13.3
pip-chill==1.0.3
pytest-asyncio==0.21.0
pytz==2023.3

77
tests/test.bash Executable file
View file

@ -0,0 +1,77 @@
#!/bin/bash
set -e
# generate certs for testing
generateCert() {
local DOMAIN="$1"
if [[ ! -d certs/"$DOMAIN" ]] ; then
mkdir -p certs/"$DOMAIN"
cd certs/"$DOMAIN"
openssl req -x509 -newkey rsa:4096 -keyout privkey.pem -out fullchain.pem -days 365 -subj "/CN=$DOMAIN" -nodes
chmod 777 *.pem
cd ../../
fi
}
registerTestUser() {
local userName="$1"
local containerName="$2"
echo "Registering TestUser '$userName' in container '$containerName'"
sudo docker compose exec "$containerName" /bin/bash -c "prosodyctl register $userName example.com 12345678"
}
registerTestUsers() {
local containerName="$1"
registerTestUser admin "$containerName"
registerTestUser user1 "$containerName"
registerTestUser user2 "$containerName"
registerTestUser user3 "$containerName"
}
runTests() {
local containerName="$1"
python --version \
&& python3 --version \
&& python3 -m venv venv \
&& source venv/bin/activate \
&& python --version \
&& pip --version \
&& pip install -r requirements.txt \
&& pytest \
&& deactivate \
&& sleep 5 \
&& sudo docker compose logs "$containerName" \
&& export batsContainerName="$containerName" \
&& ./bats/bats-core/bin/bats tests.bats \
&& ./bats/bats-core/bin/bats tests-"$containerName".bats
}
generateCert "example.com"
generateCert "conference.example.com"
generateCert "proxy.example.com"
generateCert "pubsub.example.com"
generateCert "upload.example.com"
# Run tests for first container with postgres
# Start postgres first and wait for 10 seconds before starting prosody.
sudo docker compose down
sudo docker compose up -d postgres
sleep 10
sudo docker compose up -d prosody_postgres
registerTestUsers prosody_postgres
runTests prosody_postgres
sudo docker compose down
# Run tests for second container with SQLite
sudo docker compose up -d prosody
registerTestUsers prosody
runTests prosody
sudo docker compose down
# Run tests for prosody with ldap
sudo docker compose up -d prosody_ldap
runTests prosody_ldap
sudo docker compose down

120
tests/test_prosody.py Normal file
View file

@ -0,0 +1,120 @@
import aiosasl
import aioxmpp
import aioxmpp.dispatcher
import asyncio
import pytest
@pytest.fixture
def client(client_username, password):
jid = aioxmpp.JID.fromstr(client_username)
client = aioxmpp.PresenceManagedClient(
jid,
aioxmpp.make_security_layer(
password,
no_verify=True
),
override_peer=[("localhost", 5222, aioxmpp.connector.STARTTLSConnector())],
)
return client
@pytest.fixture
def client_with_message_dispatcher(client):
def message_received(msg):
print(msg)
print(msg.body)
assert msg.body == "Hello World!"
# obtain an instance of the service
message_dispatcher = client.summon(
aioxmpp.dispatcher.SimpleMessageDispatcher
)
# register a message callback here
message_dispatcher.register_callback(
aioxmpp.MessageType.CHAT,
None,
message_received,
)
return client
@pytest.mark.asyncio
@pytest.mark.parametrize("client_username, password", [("admin@example.com", "12345678")])
async def test_send_message_from_admin_to_user1(client):
recipient_jid = aioxmpp.JID.fromstr("user1@example.com")
async with client.connected() as stream:
msg = aioxmpp.Message(
to=recipient_jid,
type_=aioxmpp.MessageType.CHAT,
)
# None is for "default language"
msg.body[None] = "Hello World!"
await client.send(msg)
@pytest.mark.asyncio
@pytest.mark.parametrize("client_username, password", [("admin@example.com", "12345678")])
async def test_send_message_from_admin_to_user2(client):
recipient_jid = aioxmpp.JID.fromstr("user2@example.com")
async with client.connected() as stream:
msg = aioxmpp.Message(
to=recipient_jid,
type_=aioxmpp.MessageType.CHAT,
)
msg.body[None] = "Hello World!"
await client.send(msg)
@pytest.mark.asyncio
@pytest.mark.parametrize("client_username, password", [("user1@example.com", "12345678")])
async def test_send_message_from_user1_to_user2(client):
recipient_jid = aioxmpp.JID.fromstr("user2@example.com")
async with client.connected() as stream:
msg = aioxmpp.Message(
to=recipient_jid,
type_=aioxmpp.MessageType.CHAT,
)
msg.body[None] = "Hello World!"
await client.send(msg)
@pytest.mark.asyncio
@pytest.mark.parametrize("client_username, password", [("user2@example.com", "12345678")])
async def test_send_message_from_user2_to_user3(client):
recipient_jid = aioxmpp.JID.fromstr("user3@example.com")
async with client.connected() as stream:
msg = aioxmpp.Message(
to=recipient_jid,
type_=aioxmpp.MessageType.CHAT,
)
msg.body[None] = "Hello World!"
await client.send(msg)
@pytest.mark.asyncio
@pytest.mark.parametrize("client_username, password", [("user2@example.com", "12345678")])
async def test_send_message_from_user2_to_nonexisting(client):
recipient_jid = aioxmpp.JID.fromstr("nonexisting@example.com")
async with client.connected() as stream:
msg = aioxmpp.Message(
to=recipient_jid,
type_=aioxmpp.MessageType.CHAT,
)
msg.body[None] = "Hello World!"
await client.send(msg)
@pytest.mark.asyncio
@pytest.mark.parametrize("client_username, password", [("user2@example.com", "wrong password")])
async def test_can_not_log_in_with_wrong_password(client):
with pytest.raises(aiosasl.AuthenticationFailure):
recipient_jid = aioxmpp.JID.fromstr("nonexisting@example.com")
async with client.connected() as stream:
msg = aioxmpp.Message(
to=recipient_jid,
type_=aioxmpp.MessageType.CHAT,
)
msg.body[None] = "Hello World!"
await client.send(msg)

10
tests/tests-prosody.bats Normal file
View file

@ -0,0 +1,10 @@
# For tests with pipes see: https://github.com/sstephenson/bats/issues/10
load 'bats/bats-support/load'
load 'bats/bats-assert/load'
@test "Should use sqlite" {
run bash -c "sudo docker compose logs $batsContainerName | grep -E \"Connecting to \[SQLite3\] \/usr\/local\/var\/lib\/prosody\/prosody\.sqlite\.\.\.\""
assert_success
assert_output
}

View file

@ -0,0 +1,16 @@
# For tests with pipes see: https://github.com/sstephenson/bats/issues/10
load 'bats/bats-support/load'
load 'bats/bats-assert/load'
@test "Should use sqlite" {
run bash -c "sudo docker compose logs $batsContainerName | grep -E \"Connecting to \[SQLite3\] \/usr\/local\/var\/lib\/prosody\/prosody\.sqlite\.\.\.\""
assert_success
assert_output
}
@test "Should use ldap" {
run bash -c "sudo docker compose logs $batsContainerName | grep -E \"Host 'example.com' now set to use user provider 'ldap'\""
assert_success
assert_output
}

View file

@ -0,0 +1,10 @@
# For tests with pipes see: https://github.com/sstephenson/bats/issues/10
load 'bats/bats-support/load'
load 'bats/bats-assert/load'
@test "Should use postgres" {
run bash -c "sudo docker compose logs $batsContainerName | grep -E \"Connecting to \[PostgreSQL\] prosody\.\.\.\""
assert_success
assert_output
}

98
tests/tests.bats Normal file
View file

@ -0,0 +1,98 @@
# For tests with pipes see: https://github.com/sstephenson/bats/issues/10
load 'bats/bats-support/load'
load 'bats/bats-assert/load'
@test "Should send 5 messages" {
run bash -c "sudo docker compose logs $batsContainerName | grep -E \"Received\[c2s\]: <message\" | wc -l"
assert_success
assert_output "5"
}
@test "Should select certificate for example.com" {
run bash -c "sudo docker compose logs $batsContainerName | grep \"Certificates loaded\" | grep \" example.com:tls\" | wc -l"
assert_success
assert_output "1"
}
@test "Should select certificate for conference.example.com" {
run bash -c "sudo docker compose logs $batsContainerName | grep \"Certificates loaded\" | grep \"conference.example.com:tls\" | wc -l"
assert_success
assert_output "1"
}
@test "Should select certificate for proxy.example.com" {
run bash -c "sudo docker compose logs $batsContainerName | grep \"Certificates loaded\" | grep \"proxy.example.com:tls\" | wc -l"
assert_success
assert_output "1"
}
@test "Should select certificate for pubsub.example.com" {
run bash -c "sudo docker compose logs $batsContainerName | grep \"Certificates loaded\" | grep \"pubsub.example.com:tls\" | wc -l"
assert_success
assert_output "1"
}
@test "Should select certificate for upload.example.com" {
run bash -c "sudo docker compose logs $batsContainerName | grep \"Certificates loaded\" | grep \"upload.example.com:tls\" | wc -l"
assert_success
assert_output "1"
}
@test "Should log error for user with wrong password" {
run bash -c "sudo docker compose logs $batsContainerName | grep \"Session closed by remote with error: undefined-condition (user intervention: authentication failed: authentication aborted by user)\""
assert_success
assert_output
}
@test "Should activate s2s" {
run bash -c "sudo docker compose logs $batsContainerName | grep -E \"Activated service 's2s' on (\[::\]:5269|\[\*\]:5269), (\[::\]:5269|\[\*\]:5269)\""
assert_success
assert_output
}
@test "Should activate c2s" {
run bash -c "sudo docker compose logs $batsContainerName | grep -E \"Activated service 'c2s' on (\[::\]:5222|\[\*\]:5222), (\[::\]:5222|\[\*\]:5222)\""
assert_success
assert_output
}
@test "Should activate c2s_direct_tls" {
run bash -c "sudo docker compose logs $batsContainerName | grep -E \"Activated service 'c2s_direct_tls' on (\[::\]:5223|\[\*\]:5223), (\[::\]:5223|\[\*\]:5223)\""
assert_success
assert_output
}
@test "Should activate proxy65" {
run bash -c "sudo docker compose logs $batsContainerName | grep -E \"Activated service 'proxy65' on (\[::\]:5000|\[\*\]:5000), (\[::\]:5000|\[\*\]:5000)\""
assert_success
assert_output
}
@test "Should activate https" {
run bash -c "sudo docker compose logs $batsContainerName | grep -E \"Activated service 'https' on (\[::\]:5281|\[\*\]:5281), (\[::\]:5281|\[\*\]:5281)\""
assert_success
assert_output
}
@test "Should load module cloud_notify" {
run bash -c "sudo docker compose logs $batsContainerName | grep \"example.com:cloud_notify.*info.*Module loaded\""
assert_success
assert_output
}
@test "Should show upload URL" {
run bash -c "sudo docker compose logs $batsContainerName | grep \"Serving 'file_share' at https:\/\/upload.example.com:5281\/file_share\""
assert_success
assert_output
}
@test "Should not use deprecated config" {
run bash -c "sudo docker compose exec $batsContainerName /bin/bash -c \"/entrypoint.bash check\" | grep 'deprecated' -A 3"
assert_failure
}
@test "Should not have warnings in log" {
run bash -c "sudo docker compose logs $batsContainerName | grep -E \"warn\""
assert_failure
}

14
update-dependencies.sh Executable file
View file

@ -0,0 +1,14 @@
#!/bin/zsh
update_luarocks() {
# Get latest luarocks version and calculate sha256 hash of the tarball
local LUAROCKS_VER=$(wget -q -O - 'https://api.github.com/repos/luarocks/luarocks/tags' | jq -r ".[0].name")
local LUAROCKS_VER=${LUAROCKS_VER#v}
local LUAROCKS_SHA256_HASH=$(wget -q -O - "https://luarocks.org/releases/luarocks-$LUAROCKS_VER.tar.gz" | sha256sum --zero | perl -lane 'print $F[0]')
# Update Dockerfile
perl -pi -e "s/LUAROCKS_VERSION=\K.*/$LUAROCKS_VER/" Dockerfile
perl -pi -e "s/LUAROCKS_SHA256=\K.*/\"$LUAROCKS_SHA256_HASH\"/" Dockerfile
}
update_luarocks