ejabberd: new appliance

This commit is contained in:
Jörg Deckert 2021-03-16 19:33:40 +01:00
parent d49bdd6dd2
commit 6e155f80ed
11 changed files with 495 additions and 0 deletions

38
ejabberd/Makefile Normal file
View File

@ -0,0 +1,38 @@
02firstboot = $(CHROOT)/etc/local.d/02firstboot.start
cert-renew.sh = $(CHROOT)/usr/local/bin/cert-renew.sh
nginx_conf = $(CHROOT)/etc/nginx/nginx.conf.orig
example_com_conf = $(CHROOT)/etc/nginx/conf.d/example.com.conf
ejabberd_example_com_conf = $(CHROOT)/etc/nginx/conf.d/ejabberd.example.com.conf
$(02firstboot): appliance/02firstboot.start
mkdir -p $(CHROOT)/etc/local.d
cp $< $@
touch $(CHROOT)/02firstboot
$(cert-renew.sh): appliance/cert-renew.sh
cp $< $@
$(nginx_conf): nginx/nginx.conf
mv $(CHROOT)/etc/nginx/nginx.conf $@
cp $< $(CHROOT)/etc/nginx/nginx.conf
$(example_com_conf): nginx/conf.d/example.com.conf
mkdir -p $(CHROOT)/etc/nginx/conf.d
cp $< $@
$(ejabberd_example_com_conf): nginx/conf.d/ejabberd.example.com.conf
mkdir -p $(CHROOT)/etc/nginx/conf.d
cp $< $@
preinstall:
# workaround for https://bugs.gentoo.org/716968
mkdir -p $(CHROOT)/etc/ssl/ejabberd
touch $(CHROOT)/etc/ssl/ejabberd/server.pem
postinstall: $(nginx_conf) $(example_com_conf) $(ejabberd_example_com_conf) $(02firstboot) $(cert-renew.sh)
# workaround for https://bugs.gentoo.org/716968
rm -rf $(CHROOT)/etc/ssl/ejabberd
# configure postgresql
sed -i 's#^PG_INITDB_OPTS=.*#PG_INITDB_OPTS="--encoding=UTF8 --locale=de_DE.UTF-8"#' $(CHROOT)/etc/conf.d/postgresql-*
rm -rf $(CHROOT)/var/lib/postgresql/*
RUN emerge --config dev-db/postgresql

View File

@ -0,0 +1,92 @@
#!/bin/bash
# variables
LABEL="DATA"
DATABASE_PASS="Di1sgPgSQLPw."
TLD="example.com"
HOST="ejabberd"
ORGNAME="Ejabberd example"
# start
set -e
PGVER=$(eselect postgresql show)
[ -e /01firstboot ] && exit 0
[ -e /02firstboot ] || exit 0
if [ ! -d "/$LABEL/var/lib/postgresql" ]; then
echo 'Start PostgeSQL DB, create ejabberd database...'
systemctl stop postgresql-$PGVER
mkdir -p "/$LABEL/var/lib"
rm -rf "/$LABEL/var/lib/postgresql.orig"
cp -a "/var/lib/postgresql" "/$LABEL/var/lib/postgresql.orig"
mv "/var/lib/postgresql" "/$LABEL/var/lib/postgresql"
ln -s "/$LABEL/var/lib/postgresql" "/var/lib/postgresql"
systemctl start postgresql-$PGVER
psql -U postgres -d postgres -c "CREATE ROLE ejabberd WITH LOGIN;"
psql -U postgres -d postgres -c "ALTER USER ejabberd WITH PASSWORD '$DATABASE_PASS';"
psql -U postgres -d postgres -c "CREATE DATABASE ejabberd WITH OWNER ejabberd;"
psql -U ejabberd -d ejabberd < /usr/share/ejabberd/sql/pg.new.sql
else
echo 'start PostgreSQL DB...'
rm -rf "/$LABEL/var/lib/postgresql.orig"
mv "/var/lib/postgresql" "/$LABEL/var/lib/postgresql.orig"
ln -s "/$LABEL/var/lib/postgresql" "/var/lib/postgresql"
systemctl start postgresql-$PGVER
fi
if [ ! -f "/$LABEL/etc/jabber/ejabberd.yml" ]; then
echo 'edit ejabberd configuration'
mkdir -p "/$LABEL/etc/jabber"
chown jabber:jabber "/$LABEL/etc/jabber"
chmod 770 "/$LABEL/etc/jabber"
cp "/etc/jabber/ejabberd.yml" "/$LABEL/etc/jabber/ejabberd.yml.orig"
mv "/etc/jabber/ejabberd.yml" "/$LABEL/etc/jabber/ejabberd.yml"
ln -s "/$LABEL/etc/jabber/ejabberd.yml" "/etc/jabber/ejabberd.yml"
sed -i 's# - localhost# - localhost\n - example.com#' "/$LABEL/etc/jabber/ejabberd.yml"
sed -i 's/listen:/### ==============\n### DATABASE SETUP\n\nlisten:/' "/$LABEL/etc/jabber/ejabberd.yml"
sed -i 's/listen:/sql_type: pgsql\nlisten:/' "/$LABEL/etc/jabber/ejabberd.yml"
sed -i 's/listen:/sql_server: "localhost"\nlisten:/' "/$LABEL/etc/jabber/ejabberd.yml"
sed -i 's/listen:/sql_database: "ejabberd"\nlisten:/' "/$LABEL/etc/jabber/ejabberd.yml"
sed -i 's/listen:/sql_username: "ejabberd"\nlisten:/' "/$LABEL/etc/jabber/ejabberd.yml"
sed -i "s/listen:/sql_password: \"$DATABASE_PASS\"\\nlisten:/" "/$LABEL/etc/jabber/ejabberd.yml"
sed -i 's/listen:/default_db: sql\nlisten:/' "/$LABEL/etc/jabber/ejabberd.yml"
sed -i 's/listen:/new_sql_schema: true\n\nlisten:/' "/$LABEL/etc/jabber/ejabberd.yml"
else
mv "/$LABEL/etc/jabber/ejabberd.yml.orig" "/$LABEL/etc/jabber/ejabberd.yml.orig-alt"
mv "/etc/jabber/ejabberd.yml" "/$LABEL/etc/jabber/ejabberd.yml.orig"
ln -s "/$LABEL/etc/jabber/ejabberd.yml" "/etc/jabber/ejabberd.yml"
fi
if [ ! -f "/$LABEL/CERTS/$HOST.$TLD/$HOST.$TLD-cert.pem" ]; then
echo 'Create certificates...'
mkdir -p "/$LABEL/CERTS/KEYS/"
mkdir -p "/$LABEL/CERTS/$HOST.$TLD"
echo "FQDN = $HOST.$TLD" > "/$LABEL/CERTS/$HOST.$TLD/$HOST.$TLD.cnf"
echo "ORGNAME = $ORGNAME" >> "/$LABEL/CERTS/$HOST.$TLD/$HOST.$TLD.cnf"
echo "ALTNAMES = DNS:$HOST.$TLD , DNS:$TLD , DNS:conference.$TLD , DNS:guest.$TLD , DNS:proxy.$TLD , DNS:pubsub.$TLD , DNS:turn.$TLD , DNS:upload.$TLD" >> "/$LABEL/CERTS/$HOST.$TLD/$HOST.$TLD.cnf"
echo -e "\n[ req ]\ndefault_bits = 4096\ndefault_md = sha256\nprompt = no\nencrypt_key = no\ndistinguished_name = dn\nreq_extensions = req_ext\ndefault_keyfile = ../KEYS/\$FQDN-key.pem\n" >> "/$LABEL/CERTS/$HOST.$TLD/$HOST.$TLD.cnf"
echo -e "\n[ dn ]\nC = DE\nO = \$ORGNAME\nCN = \$FQDN\n" >> "/$LABEL/CERTS/$HOST.$TLD/$HOST.$TLD.cnf"
echo -e "\n[ req_ext ]\nsubjectAltName = \$ALTNAMES" >> "/$LABEL/CERTS/$HOST.$TLD/$HOST.$TLD.cnf"
openssl req -x509 -new -config "/$LABEL/CERTS/$HOST.$TLD/$HOST.$TLD.cnf" -out "/$LABEL/CERTS/$HOST.$TLD/$HOST.$TLD-cert.pem" -keyout "/$LABEL/CERTS/KEYS/$HOST.$TLD-key.pem"
cp "/$LABEL/CERTS/$HOST.$TLD/$HOST.$TLD-cert.pem" "/$LABEL/CERTS/$HOST.$TLD/$HOST.$TLD-fullchain.pem"
touch "/$LABEL/CERTS/$HOST.$TLD/$HOST.$TLD-chain.pem"
fi
rm -rf /etc/ssl/ejabberd
rm -rf /etc/ssl/nginx
mkdir -p /etc/ssl
ln -sf "/$LABEL/etc/ssl/ejabberd" "/etc/ssl/ejabberd"
ln -sf "/$LABEL/etc/ssl/nginx" "/etc/ssl/nginx"
systemctl enable postgresql-$PGVER
systemctl enable ejabberd
systemctl enable nginx
/usr/local/bin/cert-renew.sh
systemctl start ejabberd
systemctl start nginx
rm /02firstboot

View File

@ -0,0 +1,64 @@
#!/bin/bash
HOST="ejabberd"
TLD="example.com"
FQDN="$HOST.$TLD"
LABEL="DATA"
CERT_DIR=/$LABEL/CERTS
CERT_EJABBERD=/$LABEL/etc/ssl/ejabberd
CERT_NGINX=/$LABEL/etc/ssl/nginx
GETREPO=""
GETUSER=""
GETPASS=""
function getCurrentVersion() {
# Get hash from latest revision
git log --format=format:%H -1
}
cd $CERT_DIR
if [ -z "$GETREPO" ]; then
GIT_REVISION=0
GIT_NEW_REVISION=1
cd $FQDN
elif [ ! -d "$FQDN" ]; then
GIT_REVISION=0
git clone "https://$GETUSER:$GETPASS@$GETREPO"
cd $FQDN
GIT_NEW_REVISION=$(getCurrentVersion)
else
cd $FQDN
GIT_REVISION=$(getCurrentVersion)
git commit -m "CRON: auto commit"
git fetch
git merge origin/master -m "Auto Merge"
GIT_NEW_REVISION=$(getCurrentVersion)
fi
echo "old: $GIT_REVISION"
echo "new: $GIT_NEW_REVISION"
if [ $GIT_REVISION != $GIT_NEW_REVISION ]
then
echo "Update Ejabberd certificate..."
mkdir -p $CERT_EJABBERD
cp $CERT_DIR/$FQDN/$FQDN-fullchain.pem $CERT_EJABBERD/server.pem
cp $CERT_DIR/KEYS/$FQDN-key.pem $CERT_EJABBERD/server.key
chown root:jabber $CERT_EJABBERD/server.*
chmod 444 $CERT_EJABBERD/server.pem
chmod 440 $CERT_EJABBERD/server.key
echo "Restart Ejabberd..."
systemctl restart ejabberd
echo "Update Nginx certificate..."
mkdir -p $CERT_NGINX
cp $CERT_DIR/$FQDN/$FQDN-fullchain.pem $CERT_NGINX/nginx.pem
cp $CERT_DIR/KEYS/$FQDN-key.pem $CERT_NGINX/nginx.key
chown nginx:nginx $CERT_NGINX/nginx.*
chmod 444 $CERT_NGINX/nginx.pem
chmod 400 $CERT_NGINX/nginx.key
echo "Restart Nginx..."
systemctl restart nginx
fi

2
ejabberd/ejabberd.cfg Normal file
View File

@ -0,0 +1,2 @@
REPO_NAMES += unitas-xmpp
REPO_URI_unitas-xmpp = https://git.unitas-network.de/Gentoo/unitas-xmpp.git

1
ejabberd/make.conf Normal file
View File

@ -0,0 +1 @@
PHP_TARGETS="php7-4"

View File

@ -0,0 +1,107 @@
server {
listen 80 default_server;
listen [::]:80 default_server;
server_name ejabberd.example.com
conference.example.com
guest.example.com
proxy.example.com
pubsub.example.com
turn.example.com
upload.example.com;
access_log /var/log/nginx/ejabberd.example.com.access_log main;
error_log /var/log/nginx/ejabberd.example.com.error_log info;
root /var/www/ejabberd.example.com/htdocs;
}
server {
listen 127.0.0.1:8443 ssl http2 default_server;
listen [::1]:8443 ssl http2 default_server;
server_name ejabberd.example.com
conference.example.com
guest.example.com
proxy.example.com
pubsub.example.com
turn.example.com
upload.example.com;
ssl_certificate /etc/ssl/nginx/nginx.pem;
ssl_certificate_key /etc/ssl/nginx/nginx.key;
access_log /var/log/nginx/ejabberd.example.com.ssl_access_log main;
error_log /var/log/nginx/ejabberd.example.com.ssl_error_log info;
root /var/www/ejabberd.example.com/htdocs;
index index.html index.php;
location ~* ^/admin/ {
proxy_pass http://127.0.0.1:5280;
proxy_set_header Host example.com;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto https;
proxy_redirect off;
proxy_buffering off;
}
location ~* ^/bosh/ {
proxy_pass http://127.0.0.1:5280;
proxy_set_header Host example.com;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto https;
proxy_redirect off;
proxy_buffering off;
}
location ~* ^/captcha/ {
proxy_pass http://127.0.0.1:5280;
proxy_set_header Host example.com;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto https;
proxy_redirect off;
proxy_buffering off;
}
location ~* ^/register/ {
proxy_pass http://127.0.0.1:5280;
proxy_set_header Host example.com;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto https;
proxy_redirect off;
proxy_buffering off;
}
location ~* ^/upload/ {
proxy_pass http://127.0.0.1:5280;
proxy_set_header Host upload.example.com;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto https;
proxy_redirect off;
proxy_buffering off;
client_max_body_size 200M;
}
location ~* ^/ws/ {
proxy_pass http://127.0.0.1:5280;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto https;
proxy_redirect off;
proxy_buffering off;
proxy_read_timeout 86400;
}
# CORS
location ~ .(ttf|ttc|otf|eot|woff|woff2|font.css|css|js)$ {
add_header Access-Control-Allow-Origin "*"; # Decide here whether you want to allow all or only a particular domain
}
}

View File

@ -0,0 +1,59 @@
server {
listen 80;
listen [::]:80;
server_name example.com;
access_log /var/log/nginx/example.com.access_log main;
error_log /var/log/nginx/example.com.error_log info;
root /var/www/example.com/htdocs;
location /.well-known/host-meta {
default_type text/xml;
add_header Access-Control-Allow-Origin *;
}
location /.well-known/host-meta.json {
default_type application/json;
add_header Access-Control-Allow-Origin *;
}
location ^~ /.well-known/acme-challenge/ {
allow all;
default_type text/plain;
return 200 "$1.abcd-efgh";
}
location / {
return 301 https://www.example.com$request_uri;
}
}
server {
listen 127.0.0.1:8443 ssl http2;
listen [::1]:8443 ssl http2;
server_name example.com;
ssl_certificate /etc/ssl/nginx/nginx.pem;
ssl_certificate_key /etc/ssl/nginx/nginx.key;
access_log /var/log/nginx/example.com.ssl_access_log main;
error_log /var/log/nginx/example.com.ssl_error_log info;
root /var/www/example.com/htdocs;
location /.well-known/host-meta {
default_type text/xml;
add_header Access-Control-Allow-Origin *;
}
location /.well-known/host-meta.json {
default_type application/json;
add_header Access-Control-Allow-Origin *;
}
location / {
return 301 https://www.example.com$request_uri;
}
}

85
ejabberd/nginx/nginx.conf Normal file
View File

@ -0,0 +1,85 @@
user nginx nginx;
worker_processes 1;
error_log /var/log/nginx/error_log info;
events {
worker_connections 1024;
use epoll;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
log_format main
'$remote_addr - $remote_user [$time_local] '
'"$request" $status $bytes_sent '
'"$http_referer" "$http_user_agent" '
'"$gzip_ratio"';
client_header_timeout 10m;
client_body_timeout 10m;
send_timeout 10m;
connection_pool_size 256;
client_header_buffer_size 1k;
large_client_header_buffers 4 2k;
request_pool_size 4k;
gzip off;
output_buffers 1 32k;
postpone_output 1460;
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 75 20;
ignore_invalid_headers on;
index index.html;
include /etc/nginx/conf.d/*.conf;
}
# "Auseinanderbasteln" von HTTPS und XMPP auf Port 443
# Der Stream-Server hört an allen Interfaces/IPs auf Port 443
# und leitet per Proxy an $upstream weiter
# Upstream wird beim ALPN "xmpp-client" auf xmppserver gemappt,
# bei den verschiedenen HTTP-ALPNs auf httpserver,
# bei allen anderen ALPNs auf httpserver.
# httpserver sind die oben definierten server,
# die deswegen nur auf localhost mit Port 8443 hören.
# xmppserver ist der TLS-Port für Clients von ejabberd
stream {
upstream httpserver {
server localhost:8443; # webserver_host:webserver_port
}
upstream xmppserver {
server localhost:5223; # xmpp_server_host:xmpp_over_tls_port
}
upstream turnserver {
server localhost:5349; # turnserver_host:turn_over_tls_port
}
map $ssl_preread_alpn_protocols $upstream {
~\bh2\b httpserver;
~\bhttp/1.1\b httpserver;
~\bh2,http/1.1\b httpserver;
~\bxmpp-client\b xmppserver;
default turnserver;
}
server {
listen 443;
listen [::]:443;
ssl_preread on;
proxy_pass $upstream;
}
}

View File

@ -0,0 +1,28 @@
# ejabberd
net-im/ejabberd
dev-erlang/p1_oauth2
dev-erlang/ezlib
dev-erlang/eimp
dev-erlang/iconv
dev-erlang/idna
dev-erlang/jiffy
dev-erlang/jose
dev-erlang/xmpp
dev-erlang/epam
dev-erlang/base64url
dev-erlang/cache_tab
dev-erlang/fast_yaml
dev-erlang/lager
dev-erlang/p1_acme
dev-erlang/p1_utils
dev-erlang/pkix
dev-erlang/mqtree
dev-erlang/fast_xml
dev-erlang/stringprep
dev-erlang/fast_tls
dev-erlang/p1_pgsql
dev-erlang/luerl
dev-erlang/esip
dev-erlang/stun
dev-erlang/yconf
dev-erlang/unicode_util_compat

11
ejabberd/package.use Normal file
View File

@ -0,0 +1,11 @@
# Nginx
app-eselect/eselect-php fpm
dev-lang/php cli curl fpm gd pdo postgres webp
media-gfx/imagemagick jpeg -openmp webp
www-servers/nginx nginx_modules_stream_map nginx_modules_stream_ssl_preread
# XMPP
net-im/ejabberd captcha postgres redis sip stun
dev-lang/erlang kpoll smp
media-gfx/imagemagick png truetype
media-libs/gd png jpeg truetype webp

8
ejabberd/world Normal file
View File

@ -0,0 +1,8 @@
app-crypt/certbot-nginx
dev-db/postgresql
dev-lang/php
dev-php/pecl-imagick
media-gfx/gd-captcha
media-gfx/imagemagick
net-im/ejabberd
www-servers/nginx