Merge branch 'master' into ccchaos

This commit is contained in:
decentral1se 2021-12-11 17:53:24 +01:00
commit 6dd5a3b0fc
Signed by: decentral1se
GPG Key ID: 03789458B3D0C410
7 changed files with 190 additions and 7 deletions

View File

@ -1,5 +1,21 @@
# Snikket Server changelog
## UNRELEASED
- Increase shared file size limit from 16MB to 100MB
- Allow configurable storage quota for shared files
- Initial support for "limited" user accounts
- Support for group chat notifications on iOS
- Configurable port range for TURN service
- Ability to see basic server metrics in the web admin interface
- Support for advanced monitoring/alerting via Prometheus
### Upgrading
If you are using a reverse proxy in front of Snikket, ensure it can
handle the new upload limit (for example, in nginx the `client_max_body_size`
option).
## beta.20210519
- Allow custom HTTP bind interface

View File

@ -31,6 +31,13 @@ data_path = "/snikket/prosody"
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
@ -77,8 +84,11 @@ modules_enabled = {
"update_notify";
"turncredentials";
"admin_shell";
"isolate_host";
"snikket_client_id";
"snikket_ios_preserve_push";
"snikket_restricted_users";
"lastlog2";
-- Spam/abuse management
"spam_reporting"; -- Allow users to report spam/abuse
@ -119,6 +129,7 @@ modules_enabled = {
-- Monitoring & maintenance
"measure_process";
"measure_active_users";
}
registration_watchers = {} -- Disable by default
@ -142,6 +153,9 @@ registration_invite_only = true
-- over what happens when a user invites someone.
allow_contact_invites = false
-- Disallow restricted users to create invitations to the server
deny_user_invites_by_roles = { "prosody:restricted" }
invites_page = ENV_SNIKKET_INVITE_URL or ("https://"..DOMAIN.."/invite/{invite.token}/");
invites_page_external = true
@ -205,6 +219,9 @@ if ENV_SNIKKET_TWEAK_TURNSERVER ~= "0" or ENV_SNIKKET_TWEAK_TURNSERVER_DOMAIN th
turncredentials_secret = ENV_SNIKKET_TWEAK_TURNSERVER_SECRET or assert(io.open("/snikket/prosody/turn-auth-secret-v2")):read("*l");
end
-- Allow restricted users access to push notification servers
isolate_except_domains = { "push.snikket.net", "push-ios.snikket.net" }
VirtualHost (DOMAIN)
authentication = "internal_hashed"
@ -243,11 +260,20 @@ Component ("groups."..DOMAIN) "muc"
"vcard_muc";
"muc_defaults";
"muc_offline_delivery";
"snikket_restricted_users";
"muc_auto_reserve_nicks";
}
restrict_room_creation = "local"
muc_local_only = { "general@groups."..DOMAIN }
muc_room_default_persistent = true
-- Default configuration for rooms (typically overwritten by the client)
muc_room_default_allow_member_invites = true
muc_room_default_persistent = true
muc_room_default_public = false
-- Enable push notifications for offline group members by default
-- (this also requires mod_muc_auto_reserve_nicks in practice)
muc_offline_delivery_default = true
default_mucs = {
{
@ -272,8 +298,13 @@ Component ("share."..DOMAIN) "http_file_share"
http_host = "share."..DOMAIN
http_external_url = "https://share."..DOMAIN.."/"
end
http_file_share_size_limit = 1024 * 1024 * 100 -- 100MB
-- 128 bits (i.e. 16 bytes) is the maximum length of a GCM auth tag, which
-- 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
if UPLOAD_STORAGE_GB then
http_file_share_global_quota = 1024 * 1024 * 1024 * UPLOAD_STORAGE_GB
end

View File

@ -7,9 +7,9 @@
vars:
prosody:
package: "prosody-trunk"
build: "1521"
build: "1544"
prosody_modules:
revision: "8b3e91249cff"
revision: "4abb33a15897"
tasks:
- import_tasks: tasks/prosody.yml
- import_tasks: tasks/supervisor.yml

View File

@ -79,6 +79,7 @@
loop:
- mod_smacks
- mod_cloud_notify
- mod_cloud_notify_extensions
- mod_cloud_notify_encrypted
- mod_cloud_notify_priority_tag
- mod_cloud_notify_filters
@ -86,7 +87,7 @@
- mod_compact_resource
- mod_conversejs
- mod_migrate_http_upload
- mod_lastlog
- mod_lastlog2
- mod_limit_auth
- mod_password_policy
- mod_roster_allinall
@ -116,11 +117,15 @@
- mod_groups_muc_bookmarks
- mod_muc_defaults
- mod_muc_local_only
- mod_muc_offline_delivery
- mod_http_host_status_check
- mod_measure_process
- mod_prometheus
- mod_spam_reporting
- mod_watch_spam_reports
- mod_isolate_host
- mod_muc_auto_reserve_nicks
- mod_measure_active_users
- name: Enable wanted modules (snikket-modules)
file:
@ -134,6 +139,7 @@
- mod_invites_bootstrap
- mod_snikket_client_id
- mod_snikket_ios_preserve_push
- mod_snikket_restricted_users
- name: "Install lua-ossl for encrypted push notifications"
apt:

View File

@ -0,0 +1,53 @@
---
title: User roles
---
# User roles
Snikket allows you to select a role for users, each role granting different
permissions.
Each user may have one of three roles:
## Administrator
This is the default role of the first user (if you're reading this, that's
probably you!).
Administrators have full control over the server, settings, users and circles.
These features can be accessed primarily through the admin panel in the
Snikket web interface.
## Normal
This is the default role for most users. It gives access to all
non-administrative server functionality.
## Limited
Limited users have various restrictions. The purpose of this role is to
allow granting someone an account on the server, only for the purposes of
communicating with other people on that server. This can be useful to provide
a guest or child account, for example.
In particular, limited users are not allowed to:
- Communicate with users on other servers
- Join group chats on other servers
- Create public channels (including on the current server)
- Invite new users to the server (regardless of whether this is enabled for
normal users).
### Caveats
The current support for limited users has some known issues. It is designed to
prevent casual misuse of the server, but it is not intended to be a foolproof
security measure. For example, limited users are still able to *receive*
messages and contact requests from other servers, even though they cannot send
them to other servers. It is expected that we will restrict incoming traffic
for limited users in a future release, after further testing.
Also note that limited accounts may have issues using non-Snikket mobile apps
that use push notifications, depending on the design of the app. This is
because the restrictions may prevent the app communicating with its'
developer's push notification services over XMPP.

View File

@ -110,16 +110,38 @@ for more information on correctly configuring reverse proxies.
### Certificate debugging commands
If everything looks okay and you're not sure what the problem could be,
you can get the error message from the debug log:
#### Checking for errors
If you think you have everything set up correctly and you're not sure what the
problem could be, check the error log:
```
docker-compose exec snikket_certs cat /var/log/letsencrypt/errors.log
```
If you get a "No such file or directory" error when running the above command,
inspect the debug log instead:
```
docker-compose exec snikket_certs cat /var/log/letsencrypt/letsencrypt.log | grep detail
```
#### Trying again
Once you have fixed any problems, you can force a new attempt with the
following command:
```
docker-compose exec snikket_certs /etc/cron.daily/certbot
```
If that command says that no certificates are due for renewal, but you need to
trigger a renewal anyway, run:
```
docker-compose exec snikket_certs su letsencrypt -- -c "certbot renew --config-dir /snikket/letsencrypt --cert-path /etc/ssl/certbot --force-renew"
```
Note that Let's Encrypt has strict [rate limits](https://letsencrypt.org/docs/rate-limits/) -
do not run these commands more often than necessary, or you may find yourself
unable to get new certificates for a while.

View File

@ -0,0 +1,55 @@
local jid_bare = require "util.jid".bare;
local um_get_roles = require "core.usermanager".get_roles;
local function load_main_host(module)
-- Check whether a user should be isolated from remote JIDs
-- If not, set a session flag that allows them to bypass mod_isolate_host
local function check_user_isolated(event)
local session = event.session;
if not session.no_host_isolation then
local bare_jid = jid_bare(session.full_jid);
local roles = um_get_roles(bare_jid, module.host);
if roles == false then return; end
if not roles or not roles["prosody:restricted"] then
-- Bypass isolation for all unrestricted users
session.no_host_isolation = true;
end
end
end
-- Add low-priority hook to run after the check_user_isolated default
-- behaviour in mod_isolate_host
module:hook("resource-bind", check_user_isolated, -0.5);
end
local function load_groups_host(module)
local primary_host = module.host:gsub("^%a+%.", "");
local function is_restricted(user_jid)
local roles = um_get_roles(user_jid, primary_host);
return not roles or roles["prosody:restricted"];
end
module:hook("muc-config-submitted/muc#roomconfig_publicroom", function (event)
if not is_restricted(event.actor) then return; end
-- Don't allow modification of this value by restricted users
return true;
end, 5);
module:hook("muc-config-form", function (event)
if not is_restricted(event.actor) then return; end -- Don't restrict admins
-- Hide the option from the config form for restricted users
local form = event.form;
for i = #form, 1, -1 do
if form[i].name == "muc#roomconfig_publicroom" then
table.remove(form, i);
end
end
end);
end
if module:get_host_type() == "component" and module:get_option_string("component_module") == "muc" then
load_groups_host(module);
else
load_main_host(module);
end