I am attempting to set up video conferencing on mattermost and the experience is stanky
Context
We use mattermost as an open source slack alternative.
They do not provide video conferencing, so the self hosted kopano web meetings plugin is used
The server is hosted inside docker on an ubuntu host vps
Installing the plugin
The instructions in the readme were followed
Setup to build the plugin:
# The plugin runs a go binary
apt install golang-go
# building requires glide to install dependencies
add repo ppa:masterminds/glide
apt install glide
# the frontend uses yarn to manage dependencies
apt install nodejs npm
npm install -g yarn
At this point the build was failing with little clue why. Using make --trace
it was discovered that yarn was installing silently.
cd-ing into the ~/go/src/stash.kopano.im/km/mattermost-plugin-kopanowebmeetings/webapp/workspaces/kopanowebmeetings
directory and running yarn install
revealed Error: pngquant failed to build, make sure that libpng-dev is installed
apt install libpng-dev
make
make dist
The dist/...tar.gz
was scp'd locally, but couldn't be uploaded
Modifying config.json inside a volume inside a container
By default plugins can't be uploaded manually. We can change that
The container is named mattermost
and runs with a user with a uid of 2000
docker cp mattermost:/mattermost/config/config.json .
vim config.json # Set PluginSettings.EnableUploads to true
sudo chown 2000:2000 config.json
docker cp config.json mattermost:/mattermost/config/config.json
docker restart mattermost
Setting up the video server
Setup
Following the docker setup instructions from the readme I have run:
sudo openssl rand -out /etc/kopano/kwm-admin-tokens.key 32
docker pull kopano/kwmserverd
docker run --rm=true --name=kwmserverd --read-only --volume /etc/kopano/kwm-admin-tokens.key:/run/secrets/kwmserverd_admin_tokens_key:ro --publish 127.0.0.1:8778:8778 kopano/kwmserverd
Error
I see the following stack trace:
time="2019-11-09T06:36:24Z" level=info msg="serve start"
panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x30 pc=0x90efdb]
goroutine 1 [running]:
net/url.(*URL).Hostname(...)
net/url/url.go:1059
main.serve(0xc0000d5680, 0xf409b8, 0x0, 0x0, 0x4, 0xa4812e)
stash.kopano.io/kwm/kwmserver/cmd/kwmserverd/serve.go:385 +0x12ab
main.commandServe.func1(0xc0000d5680, 0xf409b8, 0x0, 0x0)
stash.kopano.io/kwm/kwmserver/cmd/kwmserverd/serve.go:55 +0x53
stash.kopano.io/kwm/kwmserver/vendor/github.com/spf13/cobra.(*Command).execute(0xc0000d5680, 0xf409b8, 0x0, 0x0, 0xc0000d5680, 0xf409b8)
stash.kopano.io/kwm/kwmserver/vendor/github.com/spf13/cobra/command.go:830 +0x2aa
stash.kopano.io/kwm/kwmserver/vendor/github.com/spf13/cobra.(*Command).ExecuteC(0xf1a780, 0xc00004bf38, 0x1, 0x1)
stash.kopano.io/kwm/kwmserver/vendor/github.com/spf13/cobra/command.go:914 +0x2fb
stash.kopano.io/kwm/kwmserver/vendor/github.com/spf13/cobra.(*Command).Execute(...)
stash.kopano.io/kwm/kwmserver/vendor/github.com/spf13/cobra/command.go:864
main.main()
stash.kopano.io/kwm/kwmserver/cmd/kwmserverd/main.go:31 +0xb7
(in actuality I am running kwmserverd through Portainer with some other configuration options but this is a minimum reproduction and follows the exact readme steps)
Environment
uname -a
Linux xxxxxxx 4.15.0-54-generic #58-Ubuntu SMP Mon Jun 24 10:55:24 UTC 2019 x86_64 x86_64 x86_64 GNU/Linux
docker --version
Docker version 18.09.7, build 2d0083d
docker inspect --format='{{index .RepoDigests 0}}' kopano/kwmserverd
kopano/kwmserverd@sha256:30bb66c4645c74f0cd7788238ce9cf1478ae2fcde26a1ead7f509ab31785b7ac # 1.0.0
Investigation
Checking server.go:285
I see that config.Iss
is being accessed, and that its assignment is conditional on the flag --iss
being specified.
Other references to config.Iss include scripts/kopano-kwmserverd.binscript
which initializes the --iss
flag to https://localhost
Resolution
docker run --rm=true --name=kwmserverd --read-only --volume /etc/kopano/kwm-admin-tokens.key:/run/secrets/kwmserverd_admin_tokens_key:ro --publish 127.0.0.1:8778:8778 kopano/kwmserverd \
serve --iss=https://localhost
Nginx proxy
nginx is being used to direct the public traffic internally. Roughly:
- listen to video.solutions.land on port 443 and direct to the internal server localhost:8778 (which the docker container binds to)
- Use the shared letsencrypt wildcard cert
- Block
/api/v1/admin
and/api/kwm/v2/admin
- Forward
/api/v1
to local - Forward
/api/kwm/v2/
and/api/v1/websock
to local with a websocket upgrade
upstream video {
server localhost:8778;
keepalive 32;
}
server {
listen 443;
server_name video.solutions.land;
ssl on;
ssl_certificate /etc/letsencrypt/live/solutions.land/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/solutions.land/privkey.pem;
ssl_session_timeout 5m;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:AES:CAMELLIA:DES-CBC3-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA;
ssl_prefer_server_ciphers on;
add_header Strict-Transport-Security max-age=31536000;
location /api/v1/admin {
return 403;
}
location /api/kwm/v2/admin {
return 403;
}
location /api/v1/websocket {
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
client_max_body_size 50M;
proxy_set_header Host $http_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 $scheme;
proxy_set_header X-Frame-Options SAMEORIGIN;
proxy_buffers 256 16k;
proxy_buffer_size 16k;
client_body_timeout 60;
send_timeout 300;
lingering_timeout 5;
proxy_connect_timeout 90;
proxy_send_timeout 300;
proxy_read_timeout 90s;
proxy_pass http://video;
}
location /api/kwm/v2/ {
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
client_max_body_size 50M;
proxy_set_header Host $http_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 $scheme;
proxy_set_header X-Frame-Options SAMEORIGIN;
proxy_buffers 256 16k;
proxy_buffer_size 16k;
client_body_timeout 60;
send_timeout 300;
lingering_timeout 5;
proxy_connect_timeout 90;
proxy_send_timeout 300;
proxy_read_timeout 90s;
proxy_pass http://video;
}
location /api/v1 {
client_max_body_size 50M;
proxy_set_header Connection "";
proxy_set_header Host $http_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 $scheme;
proxy_set_header X-Frame-Options SAMEORIGIN;
proxy_buffers 256 16k;
proxy_buffer_size 16k;
proxy_read_timeout 600s;
proxy_cache mattermost_cache;
proxy_cache_revalidate on;
proxy_cache_min_uses 2;
proxy_cache_use_stale timeout;
proxy_cache_lock on;
proxy_http_version 1.1;
proxy_pass http://video;
}
}
Plugin configuration
Kopano Web Meetings Server URL: https://video.solutions.land
Kopano Web Meetings Server secure internal URL: http://kopano-videoserver:8778
Note that the internal url does not have the admin urls blocked
Blocking Error
The plugin doesn't work and causes the entire browser to display a white screen. There is an error in the console:
TypeError: "t is undefined"
which delves deep into minified code.
There is a considerable amount of traffic to the video.solutions.land endpoint which leads me to believe that the network and service setup is correct
Minified code grokking it is.
The context of the error is:
var t = Object(B.getCurrentChannel) (e),
n = t.teammate_id || '',
Searching the keyword getCurrentChannel
in the codebase leaves me to suspect that this is the file causing the issue:
src/redux/containers/HeaderButton.js
and specifically:
const currentChannel = getCurrentChannel(state)
const directTeammateId = currentChannel.teammate_id || ""
getCurrentChannel
is defined in mattermost-redux
Correcting code
Attemptingt to install on windows subsustem for linux
[WARN] The name listed in the config file (stash.kopano.io/km/mattermost-plugin-kopanowebmeetings) does not match the current location (stash.kopano.im/km/mattermost-plugin-kopanowebmeetings)
The fast way
Since the system built correctly on the ubuntu host the HeaderButton.js
file was modified, revealing yet another JS issue:
TypeError: "r is null"
Diving into the formatted minified code...
r = document.querySelector('#channel-header .kwm-start-btn');
return r && n ? r.parentNode.classList.add('active') : r.parentNode.classList.remove('active'),
r && t ? r.parentNode.setAttribute('disabled', 'true') : r.parentNode.removeAttribute('disabled'),
src/components/HeaderButton.js
This indicates that the .kwm-start-btn
was not added to the header. At this point the problem was deemed too time consuming to resolve and the exploration was dropped.