Upgrade ejabberd, fix its cookbook test suite #677

Merged
raucao merged 4 commits from chore/upgrade_ejabberd into master 2026-10-05 14:30:36 +00:00
12 changed files with 247 additions and 55 deletions

No files matched your search

@@ -1,23 +0,0 @@
---
driver:
name: vagrant
provisioner:
name: chef_zero
# You may wish to disable always updating cookbooks in CI or other testing environments.
# For example:
# always_update_cookbooks: <%= !ENV['CI'] %>
always_update_cookbooks: true
verifier:
name: inspec
platforms:
- name: ubuntu-16.04
- name: ubuntu-18.04
suites:
- name: default
run_list:
- recipe[kosmos-ejabberd::default]
attributes:
+31 -3
View File
@@ -1,6 +1,34 @@
# frozen_string_literal: true
source 'https://supermarket.chef.io'
source chef_repo: ".."
cookbook "kosmos_postgresql", path: "../kosmos_postgresql"
# community cookbooks pinned to the versions vendored for production (see the
# root Berksfile.lock), so the integration suite exercises the same cookbook set
cookbook 'apt', '= 7.3.0'
cookbook 'build-essential', '= 8.2.1'
cookbook 'firewall', '= 6.2.16'
cookbook 'hostname', '= 0.4.2'
cookbook 'hostsfile', '= 3.0.1'
cookbook 'logrotate', '= 2.2.0'
cookbook 'mysql', '= 8.7.4'
cookbook 'nginx', '= 9.0.0'
cookbook 'ntp', '= 3.4.0'
cookbook 'ohai', '= 5.2.5'
cookbook 'openssl', '= 8.5.5'
cookbook 'postfix', '= 6.4.1'
cookbook 'timezone_iii', '= 1.0.4'
cookbook 'ulimit', '= 1.0.0'
cookbook 'users', '= 5.3.1'
cookbook 'yum', '= 7.4.13'
cookbook 'yum-epel', '= 4.2.3'
# local cookbooks
cookbook 'kosmos-base', path: '../kosmos-base'
cookbook 'kosmos-nginx', path: '../kosmos-nginx'
cookbook 'kosmos-dirsrv', path: '../kosmos-dirsrv'
cookbook 'kosmos_postgresql', path: '../kosmos_postgresql'
cookbook 'kosmos-postfix', path: '../kosmos-postfix'
cookbook 'kosmos_encfs', path: '../kosmos_encfs'
cookbook 'postgresql', path: '../postgresql'
cookbook 'backup', path: '../backup'
cookbook 'tor-full', path: '../tor-full'
metadata
@@ -1,6 +1,6 @@
node.default["ejabberd"]["version"] = "25.08"
node.default["ejabberd"]["version"] = "26.09"
node.default["ejabberd"]["package_version"] = "1"
node.default["ejabberd"]["checksum"] = "e4703bc41b5843fc4b76e8b54a9380d5895f9b3dcd4795e05ad0c260ed9b9a23"
node.default["ejabberd"]["checksum"] = "cff7b46d7a614f4c345c1cd7230b1d355a7c3e1f0062e6fbb514038177e4049c"
node.default["ejabberd"]["turn_domain"] = "turn.kosmos.org"
node.default["ejabberd"]["stun_auth_realm"] = "kosmos.org"
node.default["ejabberd"]["stun_turn_port"] = 3478
@@ -0,0 +1,78 @@
---
driver:
name: dokken
chef_version: 18.2.7
pull_platform_image: false
pull_chef_image: false
memory_limit: 2147483648 # 2GB
volumes:
# saves the apt archives outside of the container
- /var/cache/apt/archives/:/var/cache/apt/archives/
transport:
name: dokken
provisioner:
name: dokken
client_rb:
# the ejabberd package starts its service as ejabberd@localhost during
# installation; keep the chef node name in sync so ERLANG_NODE matches
node_name: localhost
# skip the firewall recipe, which is not wanted inside the container
environment: development
verifier:
name: inspec
# prepare the backing services the recipe expects in production: a PostgreSQL
# server reachable as pg.kosmos.local, trusting local connections, with the
# databases used by the vhosts
lifecycle:
pre_converge:
- remote: |
bash -c '
set -e
grep -q pg.kosmos.local /etc/hosts || echo 127.0.0.1 pg.kosmos.local >> /etc/hosts
systemctl start postgresql
HBA=$(ls /etc/postgresql/*/main/pg_hba.conf | head -1)
grep -q "127.0.0.1/32 trust" "$HBA" || sed -i "1i host all all 127.0.0.1/32 trust" "$HBA"
systemctl reload postgresql
sudo -u postgres psql -c "CREATE ROLE ejabberd LOGIN CREATEDB" 2>/dev/null || true
sudo -u postgres createdb -O ejabberd ejabberd 2>/dev/null || true
sudo -u postgres createdb -O ejabberd ejabberd_5apps 2>/dev/null || true
'
platforms:
- name: ubuntu-24.04
driver:
image: dokken/ubuntu-24.04
privileged: true
pid_one_command: /usr/lib/systemd/systemd
intermediate_instructions:
# prevent APT from deleting the APT folder
- RUN rm /etc/apt/apt.conf.d/docker-clean
# let packages start their services during installation, like on a real
# node (dokken images ship policy-rc.d that blocks service starts)
- RUN rm -f /usr/sbin/policy-rc.d
- RUN apt-get update && DEBIAN_FRONTEND=noninteractive apt-get install -y postgresql
# provide the TLS material the ejabberd config expects: dhparams.pem is
# generated manually on real nodes, the certs are deployed by the
# letsencrypt recipe (not exercised in this suite)
- RUN mkdir -p /opt/ejabberd/conf && openssl dhparam -out /opt/ejabberd/conf/dhparams.pem 1024 && (for d in kosmos.org kosmos.chat 5apps.com; do openssl req -x509 -newkey rsa:2048 -nodes -days 3650 -subj "/CN=$d" -keyout /opt/ejabberd/conf/$d.key -out /opt/ejabberd/conf/$d.crt; done)
suites:
- name: default
data_bags_path: "test/integration/default/data_bags"
encrypted_data_bag_secret_key_path: "test/integration/default/encrypted_data_bag_secret"
run_list:
- recipe[kosmos-ejabberd::default]
verifier:
inspec_tests:
- test/integration/default
attributes:
# normally provided by knife-zero / the garage role on real nodes
knife_zero:
host: "127.0.0.1"
garage:
xmpp_upload_bucket: "kosmos-xmpp-uploads"
s3_api_root_domain: "s3.kosmos.org"
@@ -42,6 +42,8 @@ file "/opt/ejabberd/.erlang.cookie" do
owner "ejabberd"
group "ejabberd"
content ejabberd_credentials['erlang_cookie']
# a changed cookie is only picked up by a restart, not by a config reload
notifies :restart, "service[ejabberd]", :delayed
end
ejabberd_nodes = search(:node, "role:ejabberd")
@@ -71,7 +73,8 @@ template "/opt/ejabberd/conf/ejabberdctl.cfg" do
owner 'ejabberd'
group 'ejabberd'
variables epmd_node_name: "ejabberd@#{node['name']}"
notifies :reload, "service[ejabberd]", :delayed
# the Erlang node name is only applied by a restart, not by a config reload
notifies :restart, "service[ejabberd]", :delayed
end
postgresql_data_bag_item = data_bag_item('credentials', 'postgresql')
@@ -69,7 +69,6 @@ listen:
request_handlers:
"/api": mod_http_api
tls: false
captcha: false
-
port: 5443
ip: "::"
@@ -87,7 +86,6 @@ listen:
tls: true
## "/pub/archive": mod_http_fileserver
## register: true
captcha: false
s2s_use_starttls: optional
@@ -280,7 +278,6 @@ modules:
mod_stream_mgmt: {}
mod_s2s_dialback: {}
mod_http_api: {}
mod_muc_occupantid: {}
mod_muc_rtbl: {}
mod_s3_upload:
region: <%= @mod_s3_upload[:region] %>
@@ -0,0 +1,59 @@
{
"id": "ejabberd",
"5apps_ldap_password": {
"encrypted_data": "NwXrlbLC09jE+gKw+PuGaNqO8e1rFHvkTIW7xNfbErepZPOzSgSASYsHYQ==\n",
"iv": "Cgd04Lihul511GU/\n",
"auth_tag": "VWTzs8TyCCTdVk5fdZrCfg==\n",
"version": 3,
"cipher": "aes-256-gcm"
},
"kosmos_ldap_password": {
"encrypted_data": "F+4J2sNC+2T8zdXs02YLBTG0nNBKP8Kv/IReYwGVGVfsQiR2aqZG3rzzNwg=\n",
"iv": "C4vHPPj4JFkoI0jh\n",
"auth_tag": "M7qic/or/YPjXyFjEtyOGg==\n",
"version": 3,
"cipher": "aes-256-gcm"
},
"uploads_secret": {
"encrypted_data": "esr0B8owTy9rTW/2aFG+vBcJh+PWncxiZ8KeGi5Plhu4P8TvRrY=\n",
"iv": "aeEissRFlaFhZrN0\n",
"auth_tag": "/P6M0JbhZ+ICmb0g+V1P9A==\n",
"version": 3,
"cipher": "aes-256-gcm"
},
"admins": {
"encrypted_data": "EImT0OiChdJIJbKzABc02aQ009BBZUtO7tv7NUVdKbdaU6YWqg==\n",
"iv": "7qxiQCAUsQVVvdqN\n",
"auth_tag": "g/naI1qKKTyMWRREokXyKg==\n",
"version": 3,
"cipher": "aes-256-gcm"
},
"erlang_cookie": {
"encrypted_data": "5teN102XDkxzX+yLYMaQveFJHRObMqLyNjlkytgTMvTWFJNZKQ==\n",
"iv": "paMgCeRvSVXXcoz7\n",
"auth_tag": "tZCz68tYrLHNdoozX3YWmw==\n",
"version": 3,
"cipher": "aes-256-gcm"
},
"stun_secret": {
"encrypted_data": "6hOSI4CSpMimyE3BTcNzCe47AOA+EDy+cNrIDrnLZVlPC+o=\n",
"iv": "qSlTvzVyA1HaYqPL\n",
"auth_tag": "ODub1d75qGOH0jWBy/vQAg==\n",
"version": 3,
"cipher": "aes-256-gcm"
},
"s3_key_id": {
"encrypted_data": "2LVJNkyPIyxaeU7MxaCQpufbycPY15C1wmoDCpn1uiQ/\n",
"iv": "WwEKzWDfpY7W/Gfn\n",
"auth_tag": "P0UyvGVJXtKS4cfjt5PMDw==\n",
"version": 3,
"cipher": "aes-256-gcm"
},
"s3_secret_key": {
"encrypted_data": "sFKFQInT+k/+gJHTLTl4WvATypyKMyRr96ZxVXST2ZKxo0lBFg==\n",
"iv": "xXN7at49ot0Xtid/\n",
"auth_tag": "ap2t6UtA83du/wNNe2sKLg==\n",
"version": 3,
"cipher": "aes-256-gcm"
}
}
@@ -0,0 +1,17 @@
{
"id": "postgresql",
"ejabberd_user_password": {
"encrypted_data": "xijtK84xBV9O6NQPNMZ1RcDYLDsl8ZzV7ebbLBrK2SJ9aWp3txhqaP2t5D8=\n",
"iv": "Z/ykF64bhUktEH3L\n",
"auth_tag": "1CXtZlzSCCtjVkCDXUX2Kg==\n",
"version": 3,
"cipher": "aes-256-gcm"
},
"server_password": {
"encrypted_data": "tzeOnply5i9Efg/CcVKdpom3qPKZ/0espjFhz5EaVmaZQ2CWWsAnQcA=\n",
"iv": "VgZE26GohviDaKRH\n",
"auth_tag": "lFl6lPg/0bKT+706olGKuA==\n",
"version": 3,
"cipher": "aes-256-gcm"
}
}
@@ -0,0 +1,43 @@
# Chef InSpec test for recipe kosmos-ejabberd::default
# The Chef InSpec reference, with examples and extensive documentation, can be
# found at https://docs.chef.io/inspec/resources/
describe package('ejabberd') do
it { should be_installed }
end
describe service('ejabberd') do
it { should be_enabled }
it { should be_running }
end
describe port(5222) do
it { should be_listening }
end
describe port(5269) do
it { should be_listening }
end
describe file('/opt/ejabberd/conf/ejabberd.yml') do
it { should exist }
its('mode') { should cmp '0640' }
# BOSH and S2S are intentionally enabled and are fixed in 26.09. They must
# keep working, so guard the handlers against accidental removal.
its('content') { should match(/mod_bosh:/) }
its('content') { should match(%r{"/bosh": mod_bosh}) }
its('content') { should match(/ejabberd_s2s_in/) }
# Regression guard for the unauthenticated RCE fixed in 26.09: mod_adhoc_api
# is one of the exploit prerequisites and must never be enabled.
its('content') { should_not match(/mod_adhoc_api:/) }
# mod_muc_occupantid was merged into mod_muc in 26.02 and the standalone
# module removed, so it must not be configured anymore.
its('content') { should_not match(/mod_muc_occupantid:/) }
# the listen option 'captcha' was deprecated in 26.09
its('content') { should_not match(/^\s*captcha:/) }
end
@@ -0,0 +1 @@
GrIN04mao5nI69WUO4h7IKYsOCXtGiKSOa1zeBYbxso=
@@ -0,0 +1,12 @@
{
"name": "development",
"description": "development environment used by the Test Kitchen suite",
"json_class": "Chef::Environment",
"chef_type": "environment",
"default_attributes": {},
"override_attributes": {
"kosmos-dirsrv": {
"master_hostname": "localhost"
}
}
}
@@ -1,23 +0,0 @@
require 'serverspec'
# Required by serverspec
set :backend, :exec
describe 'ejabberd' do
describe package('ejabberd') do
it { should be_installed }
end
it 'is listening on port 5222 (client-to-server)' do
expect(port(5222)).to be_listening
end
it 'is listening on port 5269 (server-to-server)' do
expect(port(5269)).to be_listening
end
it 'runs the ejabberd service' do
expect(service('ejabberd')).to be_running
expect(service('ejabberd')).to be_enabled
end
end