Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Matrix Authentication Support for Jitsi #2375

Merged
merged 20 commits into from
Feb 10, 2023

Conversation

jakicoll
Copy link
Contributor

@jakicoll jakicoll commented Jan 4, 2023

Matrix Authentication Support for Jitsi

This extends the collection with support for seamless authentication at the Jitsi server using Matrix OpenID.

A minimal configuration to enable it would be:

matrix_jitsi_enable_auth: true
matrix_jitsi_auth_type: "matrix"
matrix_user_verification_service_uvs_access_token: "$SOME_ADMIN_ACCESS_TOKEN"

Motivation

Currently, users self-hosting Jitsi using this playbook collection can run their Jitsi server either withouth any access control or setup additional Jitsi accounts. While the former allows anybody that knows your Matrix room ids to access your conferences, the latter introduces overhead for managing additional credentials and disturbes the user experience by asking for extra credentials. Using this technique, we can have both, restriced access withouth additional credentials.

Here is how it works: On joining a conference, Element will ask the user if the conference widged may authenticate them (see screenshot below). It then request an OpenID token from the matrix server (see MSC1960 ) and passes it to the Jitsi widget.

2023-01-03_19-21

The Jitsi server can then ask the Matrix User Verification Service if the submitted token is valid and if the user is a member of the Matrix room the conference belongs to. This is done by a prosody plugin called mod-auth-matrix-user-verification. For a detailed view of the authentication flow, please refer to the diagram of that mod here.

Implementation

Unless explicitly configured, the changes from this pull request have no effect on running or new installations.

This PR introduces the following changes:

  1. New role for installing the Matrix User Verification Service
  2. Changes to Jitsi role: Installing Jitsi Prosody Mods and configuring Jitsi Auth
  3. Changes to Jitsi and nginx-proxy roles: Serving .well-known/element/jitsi from jitsi.DOMAIN
  4. We updated the Jitsi documentation on authentication and added documentation for the user verification service.

Matrix User Verification Service

A new role installs the service using the docker images from matrixdotorg/matrix-user-verification-service. We adopted this playbook collection's approach of service setup and configuration.

By default the matrix-user-verification-service uses port 3000 over the docker network. If Jitsi is not managed by this collection and the user-verification service is manually enabled, port 3000 will be exposed on 127.0.0.1. However port 3000 may clash with grafana. We have elected to give grafana the right of way and change the port to 3003, if grafana is also enabled.

Jitsi role

We added the installation of mod-auth-matrix-user-verification to the jitsi role in setup_jitsi_prosody_*. It clones a pinned version of the mod's repository to the server and copies the mod's files into the directory for prosody mods.

The already implemented 'internal' auth requires a running prosody server to set-up users. In the file roles/custom/matrix-jitsi/tasks/util/setup_jitsi_auth.yml, where this implemented, we found some comments indicating other authentication mechanisms should be implemented there as well. However, the 'matrix' machansism does not require Prosody to already run during set up. We have therefore refactored the implementation into a 'setup_jitsi_prosody_post_setup_hooks.yml', where tasks, that require a running prosody, may reside. These are not limited to authentication tasks, even though currently only the 'internal' authentication tasks reside there.

The post_setup_hook may require the prosody container be restarted (i.e. if the auth mechanism is to be changed from 'matrix' to 'internal'). We therefore introduced matrix_jitsi_prosody_require_restart as a flag to indicate such need.
This flag indicates changes, that require prosody to restart either before the post_setup_hooks (if they run) or after the install task is done, were made.

The Auth Flow requires GET parameters to be passed with the XMPP-Websocket request (/xmpp-websocket). We had to change the proxy configuration to allow this (matrix-jitsi.conf).

- proxy_pass $backend/xmpp-websocket;
+ proxy_pass $backend$request_uri;

In this regard, we were unsure, whether $request_uri or $is_args$args would be better suited.

Jitsi Well-Known File

In order to request authentication, a file containing {"auth": "openidtoken-jwt"} needs to be served from https://jitsi.domain/.well-known/element/jitsi

We propose to add it to the existing 'static-files' directory (matrix_static_files_base_path) and create the file during the jitsi role.

This approach does come with some drawbacks:

  • Unlike the matrix .well-known files, which are created in the 'matrix-base' role (where matrix_static_files_base_path is defined), the .well-known/element/jitsi file is managed from the jitsi role. We found this more fitting, since the jitsi role should be the 'configuration-owner' for the files content and also decide, whether to create/skip/delete it. Drawback: the jitsi role requires knowledge of matrix_static_files_base_path, since the nginx-proxy role also relies on this knowlege, we found this to be ok.

  • This also means all other domains (that server static files) will serve this file. (e.g. element.DOMAIN, matrix.DOMAIN ...) We don't consider that harmful. In a future pull request we would like to propose to further subdivide the 'static-files' directory. As this would require changes even for running installations (i.e. moving the current well-known files, changing the Nginx config, ..) we omited implementing this.

Caveats

We are using a similiar setup on our production matrix server since +1y and confirmed this implementation to work on a fresh test server.

Please note these caveats:

  • Not tested with clients other than Element and servers other than Synapse.
  • This might breaks jitsi conferences for federated rooms. We did not test that. However, it's of course still possible to embed conferences from another Jitsi server in such rooms.
  • We have not implemented self_build and removal for Matrix User Verification Service
  • If one were to enable guest mode, the intened security collapses. I.e. any external party with knowlege of room names can join into running conferences without any authentication. In our test no lobby was enabled and we could join rightaway.
    It seems possible to configure the requirement for a waiting-room by default (https://community.jitsi.org/t/how-to-how-do-i-use-the-new-lobby-feature/73100). We think, implementing this as a default option, when guest mode is enabled, could be beneficial.

Additional Resources

Implementation in Element: element-hq/element-web#7153
MSC1960 seeking to standardise the implementation: https://github.com/matrix-org/matrix-spec-proposals/blob/main/proposals/1960-integrations-openid.md
User Verification Service: https://github.com/matrix-org/matrix-user-verification-service
Prosody Mod auth-matrix-user-verification: https://github.com/matrix-org/prosody-mod-auth-matrix-user-verification

Linked issues

This fixes #678.

This extends the collection with support for seamless authentication at the Jitsi server using Matrix OpenID.

1. New role for installing the [Matrix User Verification Service](https://github.com/matrix-org/matrix-user-verification-service)
2. Changes to Jitsi role: Installing Jitsi Prosody Mods and configuring Jitsi Auth
3. Changes to Jitsi and nginx-proxy roles: Serving .well-known/element/jitsi from jitsi.DOMAIN
4. We updated the Jitsi documentation on authentication and added documentation for the user verification service.
######################################################################

## FIXME: Needs to be updated when there is a proper release by upstream.
matrix_user_verification_service_docker_image: "{{ matrix_user_verification_service_docker_image_name_prefix }}matrixdotorg/matrix-user-verification-service@sha256:d2aabc984dd69d258c91900c36928972d7aaef19d776caa3cd6a0fbc0e307270"
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not put these things in the role itself? Currently, the role has some version defined... which has no chance of working right now.. And then we patch it up here to make it work.

We'd better keep this in the role.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We decided to overwrite this in group_vars because the matrix-org/matrix-user-verification-service does not have any official releases after v2.0.0 (Feb 18, 2021) and we wanted to stick to a release tag in the role defaults.
This does add some clutter to the group_vars and we should have clarified the comment such that it reads:

# FIXME: When there is a new release for matrix-org/matrix-user-verification-service,
#   update matrix_user_verification_service_version in the role defaults and remove this.

We can also move the comment into the role defaults and use the working commit hash there.

In any case overwriting matrix_user_verification_service_docker_image is somewhat incorrect and we should only overwrite matrix_user_verification_service_version. I.e. matrix_user_verification_service_version="sha256:d2aabc984dd69d258c91900c36928972d7aaef19d776caa3cd6a0fbc0e307270", which unfortunately does not work since docker pull requires an '@' instead of ':' as delimiter when using a digest.

As a work around one could use branch-master as a version. We decided against this, since we did not want the container image to change without notice.

group_vars/matrix_servers Outdated Show resolved Hide resolved
group_vars/matrix_servers Outdated Show resolved Hide resolved
group_vars/matrix_servers Outdated Show resolved Hide resolved
docs/configuring-playbook-user-verification-service.md Outdated Show resolved Hide resolved
jakicoll and others added 18 commits February 6, 2023 11:58
Applying the assumption, that synapse is always managed by this playbook.
… in .env.j2.

Check for empty string instead of Null to verify if an openid_server_name is pinned.
…_server_name pinning. Updated validate_config.yml and added new checks to verify.
@jakicoll
Copy link
Contributor Author

jakicoll commented Feb 6, 2023

@spantaleev Thank you very much for reviewing. We've made the requested changes and will test the playbook again in our testing environment.

@spantaleev spantaleev merged commit 01ccec2 into spantaleev:master Feb 10, 2023
spantaleev added a commit that referenced this pull request Feb 10, 2023
@spantaleev
Copy link
Owner

I've fixed this up a bit and merged it!

Thank you for your hard work in bringing this large feature to the playbook!

@spantaleev spantaleev mentioned this pull request Feb 18, 2023
@crapo9000
Copy link

Hi,
can anyone confirm, that Jitsi Matrix auth is working? I've set everything up regarding the docs on a fresh deployment and when I try to connect to a Jitsi call (playbook managed) I just can't connect. On joining a lobby the jitsi auth is prompting:

image

No matter what I enter, I receive the following error message:

image

System logs are showing the following entries:

matrix-jitsi-prosody[30101]: c2s55a5a6262a00 info Client connected
matrix-jitsi-prosody[30101]: meet.jitsi:auth_matrix_user_verification info REQUEST_COMPLETE reason:invalid_auth_token
matrix-jitsi-prosody[30101]: meet.jitsi:auth_matrix_user_verification warn Error verifying membership err:bad-request, reason:JWT token must be provided with OpenID token and room ID
matrix-jitsi-prosody[30101]: c2s55a5a6366880 info Client connected
matrix-jitsi-prosody[30101]: c2s55a5a6366880 info Client disconnected: connection closed

@jakicoll
Copy link
Contributor Author

Are you joining the jitsi call via Element or are you trying to access Jitsi directly by navigating to jitsi.your-matrix-domain.com? The latter is not possible with Matrix User Authentication.

If you are doing the former: Does your synapse instance have a valid TLS certificate? Self-signed won't work here, since the user verification service by default requires a secure connection to your synapse server.

If none of these solve the issue, could you please:
(1) Set the matrix_user_verification_service_uvs_log_level: debug, apply that by running the playbook again including a restart of the service. Then try to join jitsi again and provide the relevant logs from the user verification service.
(2) Ensure that a JWT is passed to jitsi on loading. You could do this by opening the developer tools of your browser or Element desktop, then joining a jitsi conference and looking for the loading url in the network activity. It should look like this: https://jitsi.example.com/{{Your conference id}}?jwt={{the jwt authentification token, which is very long}}

@crapo9000
Copy link

Thank you for your fast reply! Got it working now...

Are you joining the jitsi call via Element or are you trying to access Jitsi directly by navigating to jitsi.your-matrix-domain.com? The latter is not possible with Matrix User Authentication.

-->I tried joining it via Element (browser version) with a valid wildcard LE certificate

I didn't think about using the browser debugging console until your advice. With it I found out that the issue was located at the fronting reverse proxy that is handling SSL termination etc. The only issue I still have is that jitsi isn't bringing up the conference correctly. But this seems to be a websockets/firewall problem and is not related to UVS.

Best regards!

@puhuri
Copy link

puhuri commented Apr 14, 2023

I'm not sure if this is related to the same issue (anyway, Jitsi authentication with matrix_user_verification_service_enabled does not work). Even after adding debug on UVS, there were no any request logged.

By testing at matrix-jitsi-prosody host with wget, I get following error.

wget http://matrix-user-verification-service:3000  
--2023-04-14 08:34:43--  http://matrix-user-verification-service:3000/
Resolving matrix-user-verification-service (matrix-user-verification-service)... failed: Temporary failure in name resolution.

And when I look on running docker, I can see that the matrix-jitsi-prosody is on matrix-jitsi and traefik networks and matrix-user-verification-service is on matrix only. There are no allow rules or NAT to enable access between those.

From prosody logs following can be found (obviously, JWT is invalid if it cannot communicate towards UVS).

mod_bosh                                                     info        New BOSH session, assigned it sid '83f3b2e9-c84b-413a-a32e-aa4442adb77b'
meet.jitsi:auth_matrix_user_verification                     info        REQUEST_COMPLETE reason:invalid_auth_token
meet.jitsi:auth_matrix_user_verification                     warn        Error verifying membership err:bad-request, reason:JWT token must be provided with OpenID token and room ID

The setup with Jitsi internal authentication worked without problems.

In addition, I had to remove become directives from Checkout Prosody Auth Matrix User Verification Plugin Repo as there was no user for jitsi_uid the sudo to succeed.

@crapo9000
Copy link

I'm not sure if this is related to the same issue (anyway, Jitsi authentication with matrix_user_verification_service_enabled does not work). Even after adding debug on UVS, there were no any request logged.

By testing at matrix-jitsi-prosody host with wget, I get following error.

wget http://matrix-user-verification-service:3000  
--2023-04-14 08:34:43--  http://matrix-user-verification-service:3000/
Resolving matrix-user-verification-service (matrix-user-verification-service)... failed: Temporary failure in name resolution.

And when I look on running docker, I can see that the matrix-jitsi-prosody is on matrix-jitsi and traefik networks and matrix-user-verification-service is on matrix only. There are no allow rules or NAT to enable access between those.

From prosody logs following can be found (obviously, JWT is invalid if it cannot communicate towards UVS).

mod_bosh                                                     info        New BOSH session, assigned it sid '83f3b2e9-c84b-413a-a32e-aa4442adb77b'
meet.jitsi:auth_matrix_user_verification                     info        REQUEST_COMPLETE reason:invalid_auth_token
meet.jitsi:auth_matrix_user_verification                     warn        Error verifying membership err:bad-request, reason:JWT token must be provided with OpenID token and room ID

The setup with Jitsi internal authentication worked without problems.

In addition, I had to remove become directives from Checkout Prosody Auth Matrix User Verification Plugin Repo as there was no user for jitsi_uid the sudo to succeed.

That is something, I can confirm for a external hosted docker jitsi instance (non playbook managed). On joining a conference created via the jitsi plugin it seems that UVS is not generating any JWT token to authenticate the session although the UVS port is exposed via matrix_user_verification_service_container_http_host_bind_port

@jakicoll
Copy link
Contributor Author

In addition, I had to remove become directives from Checkout Prosody Auth Matrix User Verification Plugin Repo as there was no user for jitsi_uid the sudo to succeed.

I guess that might be related to the refactoring of the jitsi installation, which has been moved into an external repository in 1d00d15 and 4546410.

Anyway, thanks for reporting. I will take a careful look as soon as we update our own matrix installation and will rise an issue if it's a regression. It might take several weeks until I can have a look, but I eventually will. :)

@crapo9000
Copy link

@jakicoll have you already been able to take a look at it?

@jakicoll
Copy link
Contributor Author

It's still on my list. Sorry, other things needed prioritization. Until then, you could of course continue to investiagate the authentication flow yourself using my hints above.

@crapo9000
Copy link

It's still on my list. Sorry, other things needed prioritization. Until then, you could of course continue to investiagate the authentication flow yourself using my hints above.

No problem. I think I came a step closer with puhuri's hint. I connected UVS container to traefik network within the UVS service file.

ExecStartPre=/usr/bin/env docker create --rm --name  matrix-user-verification-service\
                        --log-driver=none \
                        --user=972:1020 \
                        --cap-drop=ALL \
                        --read-only \
                        --network=matrix \
                        --mount type=bind,src=/matrix/user-verification-service/config/.env,dst=/app/.env,ro \
                        docker.io/matrixdotorg/matrix-user-verification-service@sha256:d2aabc984dd69d258c91900c36928972d7aaef19d776caa3cd6a0fbc0e307270

ExecStartPre=/usr/bin/env docker network connect traefik matrix-user-verification-service

ExecStart=/usr/bin/env docker start --attach matrix-user-verification-service

Original Service Template: https://github.com/spantaleev/matrix-docker-ansible-deploy/blob/master/roles/custom/matrix-user-verification-service/templates/systemd/matrix-user-verification-service.service.j2

With this change, requests are at least forwarded to UVS again as I can see in debug logs, but auth still is not working. I don't know if this could be related to my domain setup. Do you use any kind of special server delegation as described in the corresponding doc? First I tried without a DNS SRV record and UVS was checking against the base domain example.com.

In this case debug log is showing:
'Making request to: https://example.com:8448/_matrix/federation/v1/openid/userinfo?access_token=redacted'
No response received: [object Object]
User token check failed

After setting up a SRV record as mentioned here:

- ensure that you have a `_matrix._tcp` DNS SRV record for your base domain (`<your-domain>`) with a value of `10 0 8448 matrix.<your-domain>`

UVS checks against matrix.example.com but the thrown error messages are the same.
'Making request to: https://matrix.example.com:8448/_matrix/federation/v1/openid/userinfo?access_token=redacted'
No response received: [object Object]
User token check failed

Do you have any idea what the problem could be here? (This Problem btw exists too in my lab environment, that is running on the merged commit of february)

@crapo9000
Copy link

@jakicoll I finally managed to get UVS working with the traefik setup and the new implemented jitsi role. (become commands still need to be commented out in roles/galaxy/jitsi/tasks/util/setup_jitsi_auth_uvs_install.yml)Editing the systemd service file like I mentioned above already solved the internal connection issues. I just had some additional firewall issues that triggered my errors, so no further changes are required to get UVS back running.

Here is the working systemd file (/etc/systemd/system/matrix-user-verification-service.service):


[Unit]
Description=Matrix User Verification Service
Requires=docker.service
After=docker.service
Requires=matrix-synapse.service
After=matrix-synapse.service
Requires=matrix-postgres.service
After=matrix-postgres.service
DefaultDependencies=no

[Service]
Type=simple
Environment="HOME=/root"
ExecStartPre=-/usr/bin/env sh -c '/usr/bin/env docker kill matrix-user-verification-service 2>/dev/null'
ExecStartPre=-/usr/bin/env sh -c '/usr/bin/env docker rm matrix-user-verification-service 2>/dev/null'


ExecStartPre=/usr/bin/env docker create --rm --name  matrix-user-verification-service\
                        --log-driver=none \
                        --user=998:1001 \
                        --cap-drop=ALL \
                        --read-only \
                        --network=matrix \
                        --mount type=bind,src=/matrix/user-verification-service/config/.env,dst=/app/.env,ro \
                        docker.io/matrixdotorg/matrix-user-verification-service@sha256:d2aabc984dd69d258c91900c36928972d7aaef19d776caa3cd6a0fbc0e307270

ExecStartPre=/usr/bin/env docker network connect traefik matrix-user-verification-service
ExecStart=/usr/bin/env docker start --attach matrix-user-verification-service

ExecStop=-/usr/bin/env sh -c '/usr/bin/env docker kill matrix-user-verification-service 2>/dev/null'
ExecStop=-/usr/bin/env sh -c '/usr/bin/env docker rm matrix-user-verification-service 2>/dev/null'
Restart=always
RestartSec=30
SyslogIdentifier=matrix-user-verification-service

[Install]
WantedBy=multi-user.target


Some additional changes are also required to fix the jitsi widget creation due do code changes in Element. Please change the preferredDomain variable from preferredDomain to preferred_domain in https://github.com/spantaleev/matrix-docker-ansible-deploy/blob/master/roles/custom/matrix-client-element/templates/config.json.j2 and https://github.com/spantaleev/matrix-docker-ansible-deploy/blob/7d1eb7e729b219ffc6800fecf28307e309e6848b/roles/custom/matrix-base/templates/static-files/well-known/matrix-client.j2#L21 + all related config templates

@spantaleev I'm not quite familiar with Github and it's functionality, could you please update the required files and implement the changes?

Best regards!

@spantaleev
Copy link
Owner

@crapo9000, I've implemented these changes in 0a6b934 and f3445c1.

I haven't tested them, but I'm hoping they work. Let me know if you hit any issues or corrections are necessary!

@crapo9000
Copy link

@crapo9000, I've implemented these changes in 0a6b934 and f3445c1.

I haven't tested them, but I'm hoping they work. Let me know if you hit any issues or corrections are necessary!

I've pulled your changes and f3445c1 seems to break the service file. I first have to check what's causing this, but I can't say yet whether I'll be able to do it this weekend. So until we fix this, we need to override the service file manually.

0a6b934 works as expected

spantaleev added a commit that referenced this pull request Jul 28, 2023
@spantaleev
Copy link
Owner

It may have been the missing space, which I've added in 06e2ab9.

@crapo9000
Copy link

@spantaleev Sorry for my late response, but it still did not have any time to review your changes. Your adjustment in 06e2ab9 don't seem to resolve the issue of breaking the service. Maybe there is a simple way to edit the service template just like I did in my example?

@spantaleev
Copy link
Owner

What else is necesary to do to the service template to make it like your example?

If you can submit a PR with a working matrix-user-verification-service.service, that'd be helpful.

thiras added a commit to thiras/matrix-docker-ansible-deploy that referenced this pull request Oct 30, 2023
cvwright pushed a commit to cvwright/matrix-docker-ansible-deploy that referenced this pull request Jan 11, 2024
KarolosLykos pushed a commit to KarolosLykos/matrix-docker-ansible-deploy that referenced this pull request Mar 5, 2024
KarolosLykos pushed a commit to KarolosLykos/matrix-docker-ansible-deploy that referenced this pull request Mar 5, 2024
KarolosLykos pushed a commit to KarolosLykos/matrix-docker-ansible-deploy that referenced this pull request Mar 5, 2024
KarolosLykos pushed a commit to KarolosLykos/matrix-docker-ansible-deploy that referenced this pull request Mar 5, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[Question] Is Jitsi OpenID Authentication via Matrix integrated?
5 participants