Table of Contents

2021-01-04 - dziadkofon

…or a family videoconferencing system. ;) when COVID-19 pandemic started and we ended up in a lockdown i was thinking about possible options to be able to meet grandparents, even if only remotely. there were a couple of things to keep in mind. the most important were:

time has passed, it i now have a working solution for that. :) there are two parts of it – server side and client side. we'll cover the solution in this order.

server

i've chosen jitsi as a videoconferencing solution. to set it up it's enough to create a small VM in your favorite cloud, and use docker to start an instance. as usual i'm using debian as a base OS.

after creating an instance, just to this:

apt install -y docker.io docker-compose git
git clone https://github.com/jitsi/docker-jitsi-meet.git
cd docker-jitsi-meet
 
cp env.example .env
./gen-passwords.sh
vi .env # we'll come to that in a sec...
 
mkdir -p ~/.jitsi-meet-cfg/{web/letsencrypt,transcripts,prosody/config,prosody/prosody-plugins-custom,jicofo,jvb,jigasi,jibri}
 
docker-compose up -d

there are number of options that you have to and/or should change in .env file. let's go through this that are important.

HTTP_PORT and HTTPS_PORT shall be changed to standard values (i.e. 80 and 443). otherwise Let's Encrypt will not work. since HTTPS (“security” part) is my base requirement, it is a must have here.

now setup DNS entry, that will point into your newly created instance. next change PUBLIC_URL to that URL and DOCKER_HOST_ADDRESS to an actual IP address of the machine (public IP).

time for HTTPS settings. it's all very smooth – just set ENABLE_LETSECNRYPT to 1, provide LETSENCRYPT_DOMAIN (your DNS entry) and set LETCENCRYPT_EMAIL to sth you own. you'll also need to set ENABLE_HTTP_REDIRECT to 1.

while not a hard must-have, do also consider setting RESTART_POLICY to no so that web proxy will not be restarted when Let's Encrypt's certificate negotation fails. Let's Encrypt have a very strict limits on number of tries and if you screw anything with RESTART_POLICY set to anything else, you'll just blow up Let's Encrypt certs limits rates, blocking you for hours. once cert is downloaded and working, you can always set it back to unless-stopped (or whatever you like).

the 2nd part of security aspect is that you want to have authentication enabled. since this is just a simple installation, aimed for a small and trusted group, we can just manage accounts by hand and provide family members with credentials. this can be done with jitsi's internal authorization mechanism. thus let's set ENABLE_AUTH to 1, disable guests with ENABLE_GUESTS set to 0 and set AUTH_TYPE to internal. i also prefer ENABLE_RECORDINGS to be set to 0 – don't plan to use it anyway, so why bother/risk?

the last part is to add users. you can do this with a simple command:

docker-compose exec prosody prosodyctl --config /config/prosody.cfg.lua register USERNAME meet.jitsi PASSWORD

and that's it! you're now good to go! :)

client

for most of users / family members under 60, it will be as easy as opening web browser, go to your.domain.name/channel_name, login and you can talk! :)

2/3 of my time on this project was however spent to make things easy for elders, so that they can use it, too. assumption was: no prior knowledge, technically agnostic and a single-button-UI approach. after going through like a dozen of different setups and ideas, i've finally seteled up with re-using old laptops as end-user terminals. laptops are setup up in a way, that they auto-connect to the custom jitsi server upon boot, automatically login and are ready to go. when session is over, it is enough to push power button again, to turn it off. here is a ready to go recipe for the setup.

obviously a minimal installation of debian, so that it works fast and reliable + is easy to setup (forget about Windows ;)).

first install all required packages, so that you can start X11 (note: no window manager!):

apt install chromium xinit

now add a new user, that will autologon – say: johndoe.

make user auto-login. edit /etc/systemd/logind.conf and set NAutoVTs=1. then do systemctl edit getty@tty1, providing a following content:

[Service]
ExecStart=
ExecStart=-/sbin/agetty --autologin root --noclear %I 38400 linux

run systemctl enable getty@tty1 to make sure it is started upon next boot.

to connect to the service we'll just use chromium in a kiosk mode. it should also auto start, upon boot. first create file /home/johndoe/.xinitrc and make it executable. content of it will be started when X11 is started:

#!/bin/bash
set -eux -o pipefail
 
# disable power saving, screen blanking, etc...
xset -dpms
xset s off
xset s noblank
 
# hide mouse pointer
unclutter &
 
# browser in a kiosk mode
exec chromium \
    --kiosk \
    --start-fullscreen \
    --noerrdialogs \
    --disable-translate \
    --no-first-run \
    --fast \
    --fast-start \
    --disable-infobars \
    --disable-features=TranslateUI \
    --disk-cache-dir=/dev/null \
    --password-store=basic \
    "https://your.domain.name/my_private_channel_for_family"

note that while normally incognito mode is preferred for kiosk modes, here it is actually a problem, as it will show pop-ups regarding page wanting to access your mic and camera. having this breaks the assumption of having interaction-free UI, auto-starting the whole thing. thus we skip incognito mode switch and just click “allow”, so that this setting is saved.

the last thing is to actually start X11 automatically. since we already auto-login in shell, the task is as simple as creating /home/johndoe/.bash_profile with a following content:

if [ -z "$DISPLAY" ] && [ "$(tty)" = "/dev/tty1" ]
then
  while ! ping -c 4 -D "your.domain.name"
  do
    echo "$0: awaiting for the internet connection..."
    sleep 1
  done
  exec startx
fi

you can use /etc/network/interfaces and/or wicd to auto-configure network at your family member's place. now after reboot, computer will start into kiosk mode and load the right page.

last thing that it's there to cover is auto-authentication, so that it is all key-free. to do this we'll use Auto Clicker - AutoFill addon to chromium. with it you can setup auto-filling entries and / or clicking buttons on pages, using xpath to elements to interact with. in case of jitsi login screen, it is enough to import configuration similar to this (just update username, password and URL):

{
  "enable": true,
  "url": "https://your.domain.name",
  "name": "",
  "refresh": false,
  "repeat": "",
  "repeatInterval": "",
  "initWait": "",
  "startTime": "",
  "actions": [
    {
      "initWait": "",
      "xpath": "//input[@name=\"username\"]",
      "value": "johndoe",
      "repeat": "",
      "repeatInterval": "",
      "addon": {
        "xpath": "",
        "value": "",
        "condition": ""
      }
    },
    {
      "initWait": "",
      "xpath": "//input[@name=\"password\"]",
      "value": "SuperSecretRandomlyGeneratedPassword40+2",
      "repeat": "",
      "repeatInterval": "",
      "addon": {
        "xpath": "",
        "value": "",
        "condition": ""
      }
    },
    {
      "initWait": "",
      "xpath": "//button[@name=\"jqi_login_buttonspandatai18ndialogOkOKspan\"]",
      "value": "",
      "repeat": "",
      "repeatInterval": "",
      "addon": {
        "xpath": "",
        "value": "",
        "condition": ""
      }
    }
  ]
}

now we're set! after reboot it should connect, auto-login and join an appropriate channel on its own. :)

final thoughts

setup is neat and fast. on my VERY old laptop it took under 60s from pressing a button to get teleconference running, while over half of it was BIOS + awaiting for an internet connection.

the instructions are detailed enough, it could be automated. maybe in a future i'll prepare ansible's playbook for this. for now time-to-market was critical, thus i just focused on “getting the job done”.

the “non-incognito” thing could be improved. maybe it is possible to auto-access mic/cam dialog, too? or there is –do-not-bother-user flag? ;) dunno – time will tell.

i already had a great fun using the system and had a chance to see family members i have not seen for a VERY long time now. hope you'll find it useful, too! :)