generated from coop-cloud/example
Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 1ab7340949 |
@ -17,7 +17,7 @@ x-environment: &default-env
|
||||
|
||||
services:
|
||||
app:
|
||||
image: snikket/snikket-web-proxy:beta.20220119.1
|
||||
image: snikket/snikket-web-proxy:stable.20240926
|
||||
networks:
|
||||
- proxy
|
||||
- backend
|
||||
@ -42,13 +42,13 @@ services:
|
||||
- "coop-cloud.${STACK_NAME}.version=0.1.0+beta.20220119.1"
|
||||
|
||||
portal:
|
||||
image: snikket/snikket-web-portal:beta.20220119.1
|
||||
image: snikket/snikket-web-portal:stable.20240926
|
||||
environment: *default-env
|
||||
networks:
|
||||
- backend
|
||||
|
||||
server:
|
||||
image: snikket/snikket-server:beta.20220119.1
|
||||
image: snikket/snikket-server:stable.20240926
|
||||
secrets:
|
||||
- coturn_secret
|
||||
configs:
|
||||
|
||||
@ -1,27 +1,34 @@
|
||||
-- fork of https://github.com/snikket-im/snikket-server/blob/master/ansible/files/prosody.cfg.lua
|
||||
-- fork of https://github.com/snikket-im/snikket-server/blob/stable.20240926/ansible/files/prosody.cfg.lua
|
||||
-- added changes from https://github.com/3-w-c/snikket-server/blob/d8577e0e57a79afd48695aadc60f7873b56897bc/ansible/files/prosody.cfg.lua
|
||||
-- until https://github.com/snikket-im/snikket-server/issues/88 is resolved
|
||||
|
||||
local function split(s)
|
||||
local v = {};
|
||||
for p in (s or ""):gmatch("[^%s,]+") do
|
||||
v[#v+1] = p;
|
||||
end
|
||||
return v;
|
||||
end
|
||||
|
||||
local DOMAIN = Lua.assert(ENV_SNIKKET_DOMAIN, "Please set the SNIKKET_DOMAIN environment variable")
|
||||
|
||||
local CERT_PATH = ENV_SNIKKET_CERTFILE or "/etc/prosody/certs/"..DOMAIN..".crt";
|
||||
local KEY_PATH = ENV_SNIKKET_KEYFILE or "/etc/prosody/certs/"..DOMAIN..".key";
|
||||
|
||||
local DOMAIN = assert(ENV_SNIKKET_DOMAIN, "Please set the SNIKKET_DOMAIN environment variable")
|
||||
local RETENTION_DAYS = Lua.tonumber(ENV_SNIKKET_RETENTION_DAYS) or 7;
|
||||
local UPLOAD_STORAGE_GB = Lua.tonumber(ENV_SNIKKET_UPLOAD_STORAGE_GB);
|
||||
|
||||
local RETENTION_DAYS = tonumber(ENV_SNIKKET_RETENTION_DAYS) or 7;
|
||||
local UPLOAD_STORAGE_GB = tonumber(ENV_SNIKKET_UPLOAD_STORAGE_GB);
|
||||
|
||||
if prosody.process_type == "prosody" and not prosody.config_loaded then
|
||||
if Lua.prosody.process_type == "prosody" and not Lua.prosody.config_loaded then
|
||||
-- Wait at startup for certificates
|
||||
local lfs, socket = require "lfs", require "socket";
|
||||
local cert_path = "/etc/prosody/certs/"..DOMAIN..".crt";
|
||||
local counter = 0;
|
||||
while not lfs.attributes(CERT_PATH, "mode") do
|
||||
counter = counter + 1;
|
||||
if counter == 1 or counter%6 == 0 then
|
||||
print("Waiting for certificates...");
|
||||
Lua.print("Waiting for certificates...");
|
||||
elseif counter > 60 then
|
||||
print("No certificates found... exiting");
|
||||
os.exit(1);
|
||||
Lua.print("No certificates found... exiting");
|
||||
Lua.os.exit(1);
|
||||
end
|
||||
socket.sleep(5);
|
||||
end
|
||||
@ -38,11 +45,6 @@ pidfile = "/var/run/prosody/prosody.pid"
|
||||
|
||||
admin_shell_prompt = ("prosody [%s]> "):format(DOMAIN)
|
||||
|
||||
-- Aggressive GC to reduce resource consumption. These values are not
|
||||
-- incredibly scientific, but should be good for a small private server.
|
||||
-- They should be reviewed on the upgrade to Lua 5.4.
|
||||
gc = { threshold = 100, speed = 750 }
|
||||
|
||||
modules_enabled = {
|
||||
|
||||
-- Generally required
|
||||
@ -57,6 +59,7 @@ modules_enabled = {
|
||||
"blocklist"; -- Allow users to block communications with other users
|
||||
"vcard4"; -- User profiles (stored in PEP)
|
||||
"vcard_legacy"; -- Conversion between legacy vCard and PEP Avatar, vcard
|
||||
"password_policy";
|
||||
|
||||
-- Nice to have
|
||||
"version"; -- Replies to server version requests
|
||||
@ -67,6 +70,19 @@ modules_enabled = {
|
||||
"mam"; -- Store messages in an archive and allow users to access it
|
||||
"csi_simple"; -- Simple Mobile optimizations
|
||||
|
||||
-- SASL2/FAST
|
||||
"sasl2";
|
||||
"sasl2_bind2";
|
||||
"sasl2_sm";
|
||||
"sasl2_fast";
|
||||
"client_management";
|
||||
|
||||
-- Event auditing
|
||||
"audit";
|
||||
"audit_auth"; -- Audit authentication attempts and new clients
|
||||
"audit_status"; -- Audit status changes of the server (start, stop, crash)
|
||||
"audit_user_accounts"; -- Audit status changes of user accounts (created, deleted, etc.)
|
||||
|
||||
-- Push notifications
|
||||
"cloud_notify";
|
||||
"cloud_notify_extensions";
|
||||
@ -87,26 +103,25 @@ modules_enabled = {
|
||||
"bookmarks";
|
||||
"update_check";
|
||||
"update_notify";
|
||||
"turncredentials";
|
||||
"turn_external";
|
||||
"admin_shell";
|
||||
"isolate_host";
|
||||
"snikket_client_id";
|
||||
"snikket_ios_preserve_push";
|
||||
"snikket_restricted_users";
|
||||
"lastlog2";
|
||||
"admin_blocklist";
|
||||
"snikket_server_vcard";
|
||||
|
||||
-- Spam/abuse management
|
||||
"spam_reporting"; -- Allow users to report spam/abuse
|
||||
"watch_spam_reports"; -- Alert admins of spam/abuse reports by users
|
||||
"server_contact_info"; -- Publish contact information for this service
|
||||
|
||||
-- TODO...
|
||||
--"groups"; -- Shared roster support
|
||||
--"server_contact_info"; -- Publish contact information for this service
|
||||
--"announce"; -- Send announcement to all online users
|
||||
--"motd"; -- Send a message to users when they log in
|
||||
"welcome"; -- Welcome users who register accounts
|
||||
"http_files"; -- Serve static files from a directory over HTTP
|
||||
"reload_modules";
|
||||
|
||||
-- Invites
|
||||
"invites";
|
||||
@ -137,23 +152,41 @@ modules_enabled = {
|
||||
"measure_active_users";
|
||||
"measure_lua";
|
||||
"measure_malloc";
|
||||
"portcheck";
|
||||
}
|
||||
|
||||
registration_watchers = {} -- Disable by default
|
||||
registration_notification = "New user registered: $username"
|
||||
|
||||
reload_global_modules = { "http" }
|
||||
contact_info = {
|
||||
abuse = ENV_SNIKKET_ABUSE_EMAIL and {"mailto:"..ENV_SNIKKET_ABUSE_EMAIL} or nil;
|
||||
security = ENV_SNIKKET_SECURITY_EMAIL and {"mailto:"..ENV_SNIKKET_SECURITY_EMAIL} or nil;
|
||||
}
|
||||
|
||||
http_ports = { ENV_SNIKKET_TWEAK_INTERNAL_HTTP_PORT or 5280 }
|
||||
http_interfaces = { ENV_SNIKKET_TWEAK_INTERNAL_HTTP_INTERFACE or "127.0.0.1" }
|
||||
http_max_content_size = 1024 * 1024 -- non-streaming uploads limited to 1MB (improves RAM usage)
|
||||
|
||||
https_ports = {};
|
||||
|
||||
c2s_direct_tls_ports = { 5223 }
|
||||
|
||||
proxy65_ports = { ENV_SNIKKET_PROXY65_PORT or 5000 }
|
||||
|
||||
allow_registration = true
|
||||
registration_invite_only = true
|
||||
|
||||
password_policy = {
|
||||
length = 10;
|
||||
}
|
||||
|
||||
-- In the future we want to switch to SASL2 for better security,
|
||||
-- as client ids are not supported in SASL1 (identification is via
|
||||
-- the resource string, which is semi-public and not authenticated)
|
||||
-- This tweak is for developers to test with the future configuration,
|
||||
-- or people who want to opt into the new security sooner.
|
||||
enforce_client_ids = ENV_SNIKKET_TWEAK_REQUIRE_SASL2 == "1"
|
||||
|
||||
-- This disables in-app invites for non-admins
|
||||
-- TODO: The plan is to enable it once we can
|
||||
-- give the admin more fine-grained control
|
||||
@ -163,24 +196,46 @@ allow_contact_invites = false
|
||||
-- Disallow restricted users to create invitations to the server
|
||||
deny_user_invites_by_roles = { "prosody:restricted" }
|
||||
|
||||
-- This role was renamed 'guest' in Prosody.
|
||||
custom_roles = { { name = "prosody:restricted"; priority = 15 } }
|
||||
|
||||
invites_page = ENV_SNIKKET_INVITE_URL or ("https://"..DOMAIN.."/invite/{invite.token}/");
|
||||
invites_page_external = true
|
||||
|
||||
invites_bootstrap_index = tonumber(ENV_TWEAK_SNIKKET_BOOTSTRAP_INDEX)
|
||||
invites_bootstrap_index = Lua.tonumber(ENV_TWEAK_SNIKKET_BOOTSTRAP_INDEX)
|
||||
invites_bootstrap_secret = ENV_TWEAK_SNIKKET_BOOTSTRAP_SECRET
|
||||
invites_bootstrap_ttl = Lua.tonumber(ENV_TWEAK_SNIKKET_BOOTSTRAP_TTL or (28 * 86400)) -- default 28 days
|
||||
|
||||
-- The Resource Owner Credentials grant used internally between the web portal
|
||||
-- and Prosody, so ensure this is enabled. Other unused flows can be disabled.
|
||||
allowed_oauth2_grant_types = { "password" }
|
||||
allowed_oauth2_response_types = {}
|
||||
|
||||
-- Longer access token lifetime than the default
|
||||
-- TODO: Use the already longer-lived refresh tokens
|
||||
oauth2_access_token_ttl = 86400
|
||||
|
||||
c2s_require_encryption = true
|
||||
s2s_require_encryption = true
|
||||
s2s_secure_auth = true
|
||||
|
||||
-- Grant federation privileges to regular users but not restricted users.
|
||||
-- This is enforced by mod_isolate_host.
|
||||
add_permissions = {
|
||||
["prosody:registered"] = {
|
||||
"xmpp:federate";
|
||||
};
|
||||
}
|
||||
|
||||
archive_expires_after = ("%dd"):format(RETENTION_DAYS) -- Remove archived messages after N days
|
||||
|
||||
-- Disable IPv6 by default because Docker does not
|
||||
-- have it enabled by default, and s2s to domains
|
||||
-- with A+AAAA records breaks (as opposed to just AAAA)
|
||||
-- TODO: implement happy eyeballs in net.connect
|
||||
-- https://issues.prosody.im/1246
|
||||
use_ipv6 = (ENV_SNIKKET_TWEAK_IPV6 == "1")
|
||||
-- Delay full account deletion via IBR for RETENTION_DAYS, to allow restoration
|
||||
-- in case of accidental or malicious deletion of an account
|
||||
registration_delete_grace_period = ("%d days"):format(RETENTION_DAYS)
|
||||
|
||||
-- Allow disabling IPv6 because Docker does not have it enabled by default, but
|
||||
-- we don't use Docker networking so it should not matter.
|
||||
use_ipv6 = (ENV_SNIKKET_TWEAK_IPV6 ~= "0")
|
||||
|
||||
log = {
|
||||
[ENV_SNIKKET_LOGLEVEL or "info"] = "*stdout"
|
||||
@ -188,7 +243,18 @@ log = {
|
||||
|
||||
authentication = "internal_hashed"
|
||||
authorization = "internal"
|
||||
storage = "internal"
|
||||
disable_sasl_mechanisms = { "PLAIN", "OAUTHBEARER" }
|
||||
|
||||
if ENV_SNIKKET_TWEAK_STORAGE == "sqlite" then
|
||||
storage = "sql"
|
||||
sql = {
|
||||
driver = "SQLite3";
|
||||
database = "/snikket/prosody/prosody.sqlite";
|
||||
}
|
||||
else
|
||||
storage = "internal"
|
||||
end
|
||||
|
||||
statistics = "internal"
|
||||
|
||||
if ENV_SNIKKET_TWEAK_PROMETHEUS == "1" then
|
||||
@ -203,10 +269,24 @@ else
|
||||
statistics_interval = 60
|
||||
end
|
||||
|
||||
-- certificates = "certs"
|
||||
if ENV_SNIKKET_TWEAK_DNSSEC == "1" then
|
||||
local trustfile = "/usr/share/dns/root.ds"; -- Requires apt:dns-root-data
|
||||
-- Bail out if it doesn't work
|
||||
Lua.assert(Lua.require"lunbound".new{ resolvconf = true; trustfile = trustfile }:resolve ".".secure,
|
||||
"Upstream DNS resolver is not DNSSEC-capable. Fix this or disable SNIKKET_TWEAK_DNSSEC");
|
||||
unbound = { trustfile = trustfile }
|
||||
|
||||
-- Since we have DNSSEC, we can also do DANE
|
||||
use_dane = true
|
||||
end
|
||||
|
||||
certificates = "certs"
|
||||
|
||||
group_default_name = ENV_SNIKKET_SITE_NAME or DOMAIN
|
||||
|
||||
site_name = ENV_SNIKKET_SITE_NAME or DOMAIN
|
||||
site_logo = "/usr/local/share/snikket/logo.png"
|
||||
|
||||
-- Update check configuration
|
||||
software_name = "Snikket"
|
||||
update_notify_version_url = "https://snikket.org/updates/{branch}/{version}"
|
||||
@ -223,8 +303,10 @@ http_host = DOMAIN
|
||||
http_external_url = "https://"..DOMAIN.."/"
|
||||
|
||||
if ENV_SNIKKET_TWEAK_TURNSERVER ~= "0" or ENV_SNIKKET_TWEAK_TURNSERVER_DOMAIN then
|
||||
turncredentials_host = ENV_SNIKKET_TWEAK_TURNSERVER_DOMAIN or DOMAIN
|
||||
turncredentials_secret = ENV_SNIKKET_TWEAK_TURNSERVER_SECRET or assert(io.open("/snikket/prosody/turn-auth-secret-v2")):read("*l");
|
||||
turn_external_host = ENV_SNIKKET_TWEAK_TURNSERVER_DOMAIN or DOMAIN
|
||||
turn_external_port = ENV_SNIKKET_TWEAK_TURNSERVER_PORT
|
||||
turn_external_secret = ENV_SNIKKET_TWEAK_TURNSERVER_SECRET or Lua.assert(Lua.io.open("/snikket/prosody/turn-auth-secret-v2")):read("*l");
|
||||
turn_external_tcp = true
|
||||
end
|
||||
|
||||
-- Allow restricted users access to push notification servers
|
||||
@ -239,6 +321,9 @@ VirtualHost (DOMAIN)
|
||||
key = KEY_PATH;
|
||||
};
|
||||
|
||||
modules_enabled = {}
|
||||
firewall_scripts = {}
|
||||
|
||||
http_files_dir = "/var/www"
|
||||
http_paths = {
|
||||
files = "/";
|
||||
@ -248,29 +333,57 @@ VirtualHost (DOMAIN)
|
||||
}
|
||||
|
||||
if ENV_SNIKKET_TWEAK_PROMETHEUS == "1" then
|
||||
modules_enabled = {
|
||||
modules_enabled: append {
|
||||
"http_openmetrics";
|
||||
}
|
||||
end
|
||||
|
||||
welcome_message = [[Hi, welcome to Snikket on $host! Thanks for joining us.]]
|
||||
.."\n\n"
|
||||
..[[For help and enquiries related to this service you may contact the admin via email: ]]
|
||||
..ENV_SNIKKET_ADMIN_EMAIL
|
||||
.."\n\n"
|
||||
..[[Happy chatting!]]
|
||||
if ENV_SNIKKET_TWEAK_S2S_STATUS == "1" then
|
||||
modules_enabled: append {
|
||||
"s2s_status";
|
||||
}
|
||||
end
|
||||
|
||||
if ENV_SNIKKET_TWEAK_PUSH2 == "1" then
|
||||
modules_enabled: append {
|
||||
"push2";
|
||||
}
|
||||
end
|
||||
|
||||
if ENV_SNIKKET_TWEAK_RESTRICTED_USERS_V2 == "1" then
|
||||
firewall_scripts: append {
|
||||
"/etc/prosody/firewall/restricted_users.pfw";
|
||||
}
|
||||
else
|
||||
modules_enabled: append {
|
||||
"isolate_host";
|
||||
}
|
||||
end
|
||||
|
||||
|
||||
Component ("groups."..DOMAIN) "muc"
|
||||
modules_enabled = {
|
||||
"muc_mam";
|
||||
"muc_moderation";
|
||||
"muc_local_only";
|
||||
"vcard_muc";
|
||||
"muc_defaults";
|
||||
"muc_offline_delivery";
|
||||
"snikket_restricted_users";
|
||||
"snikket_deprecate_general_muc";
|
||||
"muc_auto_reserve_nicks";
|
||||
}
|
||||
|
||||
if ENV_SNIKKET_TWEAK_S2S_STATUS == "1" then
|
||||
modules_enabled: append {
|
||||
"s2s_status";
|
||||
}
|
||||
end
|
||||
|
||||
restrict_room_creation = "local"
|
||||
|
||||
-- Some older deployments may have the general@ MUC, so we still need
|
||||
-- to protect it:
|
||||
muc_local_only = { "general@groups."..DOMAIN }
|
||||
|
||||
-- Default configuration for rooms (typically overwritten by the client)
|
||||
@ -285,22 +398,6 @@ Component ("groups."..DOMAIN) "muc"
|
||||
-- to detect whether push notifications are enabled)
|
||||
muc_registration_include_form = true
|
||||
|
||||
default_mucs = {
|
||||
{
|
||||
jid_node = "general";
|
||||
config = {
|
||||
name = "General Chat";
|
||||
description = "Welcome to "..DOMAIN.." general chat!";
|
||||
change_subject = false;
|
||||
history_length = 30;
|
||||
members_only = false;
|
||||
moderated = false;
|
||||
persistent = true;
|
||||
public = true;
|
||||
public_jids = true;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
Component ("share."..DOMAIN) "http_file_share"
|
||||
-- For backwards compat, allow HTTP upload on the base domain
|
||||
@ -313,7 +410,7 @@ Component ("share."..DOMAIN) "http_file_share"
|
||||
-- is appended to encrypted uploads according to XEP-0454. This ensures we
|
||||
-- allow files up to the size limit even if they are encrypted.
|
||||
http_file_share_size_limit = (1024 * 1024 * 100) + 16 -- 100MB + 16 bytes
|
||||
http_file_share_expire_after = 60 * 60 * 24 * RETENTION_DAYS -- N days
|
||||
http_file_share_expires_after = 60 * 60 * 24 * RETENTION_DAYS -- N days
|
||||
|
||||
if UPLOAD_STORAGE_GB then
|
||||
http_file_share_global_quota = 1024 * 1024 * 1024 * UPLOAD_STORAGE_GB
|
||||
@ -322,4 +419,8 @@ Component ("share."..DOMAIN) "http_file_share"
|
||||
file_share = "/upload"
|
||||
}
|
||||
|
||||
modules_disabled = {
|
||||
"s2s";
|
||||
}
|
||||
|
||||
Include (ENV_SNIKKET_TWEAK_EXTRA_CONFIG or "/snikket/prosody/*.cfg.lua")
|
||||
|
||||
Reference in New Issue
Block a user