With everything going on in the world with COVID-19 and the social distancing that is happening, people are looking to connect with friends, family and co-workers via Video conferencing more than ever. Recent vulnerabilities in Zoom have made people more cognizant than ever that security needs to be considered when using these platforms no matter what you are using them for.
Jitsi is an open source video conferencing platform that I’ve been hearing about a lot lately, and finally had a chance to look into. In this post I’ll explain how to use Terraform to provision a Jitsi instance when you need a conference and tear it down when you are done. We’ll be using Vultr and their Jitsi “application” and AWS Route 53 for DNS.
Table of Contents
Why Am I Writing This Article, and What Does It Accomplish?
Why am I writing this article?
- We always want to have our apps and infrastructure defined in code
- We pay for traditional web conferencing software 24 hours a day, 7 days a week, regardless of if we are are using running a conference or not. Why don’t we spin up conference infrastructure when we need it, and tear it down when we don’t?
At a high level, this project will accomplish the following:
- Provision a Vultr VPS that is pre-configured with Jitsi
- Take the IP Address that Vultr assigns the VPS and use it to create an A Record in Route 53
- Copy a script to your VPS that will be used to finish the Jitsi configuration
- Run the script that we copied and pass a few command line arguments that are specific to our environment
Prerequisites
In addition to having Terraform downloaded and installed, we’ll need the following items:
Vultr Account + API Access
Vultr is definitely my go-to for VPS’s these days. Not only because of their price/performance/feature availability ratio, but because they provide a number of pre-configured applications that are ready, or near ready for use. Jitsi is one of these applications. If you do use Vultr, please do me a favor and use this link to sign up. Iโll get a little kickback, but youโll get $100 USD to use on the site in your first month.
Once you have a Vultr account, you’ll need to generate and record an API key to use with Terraform. Use the steps below to generate it.
- Log into Vultr
- Navigate to Settings, and then API
- Generate an API key, and copy it somewhere safe, we’ll be using it later
AWS Account + API Access
We’ll be using AWS’s Route 53 service, which is really just a fancy DNS service that’s hooked into AWS. In order to automate Route 53 with Terraform, we’ll need to enable API access.
Use this link to access the IAM Management page
- Expand the “Access Keys” blade
- Select “Create New Access Key
- Save the resulting file, as we’ll use the contents later
Domain Registrar Using Custom Nameservers
In addition to the above, the domain you want to use will need to be configured to use the Route 53 Name Servers. Route 53 will provide you the nameservers when you create a zone, and you’ll simply plug those into your registrar DNS settings page. I’m not going to explain how to create a zone in Route 53, or how to configure your registrar, but if you have questions, throw them in the comments and I’ll do my best to help.
Getting Started
Run This Project
- Grab the files below, or copy them from my Github Repository
- Enter the directory that contains the files
- At a minimum, modify the fields in the auto.tfvars file
- vultr_api_key
- aws_access_key
- aws_secret_key
- domain
- Initialize Terraform by running
terraform init
- Create a terraform plan by running
terraform plan
- Apply the configuration by running
terraform apply
- Voila! In less than 5 minutes, you’ve got a functional, secure Jitsi instance, running on a server and domain you control. Upon successful creation, you’ll see text like what we see below giving you the URL and credentials. When you are done with your conference, just run
terraform destroy
to stop from receiving charges on a server/service you aren’t using.
1
2
3
4
5
6
7
8
9
|
null_resource.jitsi_config (remote-exec): ------------------------------
null_resource.jitsi_config (remote-exec): | |
null_resource.jitsi_config (remote-exec): | JITSI SETUP COMPLETED! |
null_resource.jitsi_config (remote-exec): | |
null_resource.jitsi_config (remote-exec): ------------------------------
null_resource.jitsi_config (remote-exec): JITSI URL: https://conference.yourdomain.com
null_resource.jitsi_config (remote-exec): USERNAME: admin
null_resource.jitsi_config (remote-exec): PASSWORD: @#$asdfahgsd34579--23%4asdf
|
Code
Main.tf
This file does all of the work.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
|
#main.tf
#https://www.virtjunkie.com/jitsi-jit-conferencing-tf-vultr-route53/
#https://github.com/jonhowe/Virtjunkie.com/tree/master/Jitsi-JIT-Conferencing-TF-Vultr-Route53
#Conifugre the Vultr provider
provider "vultr" {
api_key = var.vultr_api_key
rate_limit = 700
retry_limit = 3
}
#Configure the AWS Provider
provider "aws" {
#profile = "default"
#shared_credentials_file = "/home/jhowe/storage/btsync/folders/Sync/awscredentials/credentials"
region = var.aws_region
access_key = var.aws_access_key
secret_key = var.aws_secret_key
}
#https://www.terraform.io/docs/providers/aws/d/route53_zone.html
data "aws_route53_zone" "selected" {
name = "${var.domain}."
private_zone = false
}
#Provision Vultr Server
resource "vultr_server" "my_server" {
plan_id = var.vultr_plan_id
region_id = var.vultr_region
app_id = var.vultr_app_id
label = "${var.hostname}.${var.domain}"
tag = var.vultr_tag
hostname = "${var.hostname}.${var.domain}"
enable_ipv6 = false
auto_backup = false
ddos_protection = false
notify_activate = false
connection {
type = "ssh"
user = "root"
#https://www.terraform.io/docs/providers/vultr/r/server.html#default_password
password = self.default_password
#https://www.terraform.io/docs/provisioners/connection.html#the-self-object
host = self.main_ip
}
provisioner "local-exec" {
command = "echo SSH to this server with the command: ssh root@${vultr_server.my_server.main_ip} with the password '${vultr_server.my_server.default_password}'"
}
}
#Create the Route 53 A Record
#https://www.terraform.io/docs/providers/aws/r/route53_record.html
resource "aws_route53_record" "conference" {
zone_id = data.aws_route53_zone.selected.zone_id
name = "${var.hostname}.${data.aws_route53_zone.selected.name}"
type = "A"
ttl = "300"
records = ["${vultr_server.my_server.main_ip}"]
}
#This null resource exists to handle configuration of the Vultr VPS after Route 53
resource "null_resource" "jitsi_config" {
connection {
type = "ssh"
user = "root"
#https://www.terraform.io/docs/providers/vultr/r/server.html#default_password
password = vultr_server.my_server.default_password
#https://www.terraform.io/docs/provisioners/connection.html#the-self-object
host = vultr_server.my_server.main_ip
}
provisioner "file" {
source = "./configure_jitsi_param.sh"
destination = "/root/configure_jitsi_param.sh"
}
provisioner "remote-exec" {
inline = [
"chmod +x /root/configure_jitsi_param.sh",
"/root/configure_jitsi_param.sh ${var.hostname}.${var.domain} ${var.email} y"
]
}
}
|
Variables.tf
This file defines the variables that we will use in main.tf
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
|
#variables.tf
#https://www.virtjunkie.com/jitsi-jit-conferencing-tf-vultr-route53/
#https://github.com/jonhowe/Virtjunkie.com/tree/master/Jitsi-JIT-Conferencing-TF-Vultr-Route53
variable "vultr_api_key" {
description = "API Key Used by Vultr (https://my.vultr.com/settings/#settingsapi)"
}
variable "vultr_region" {
description = "Vultr Region Selection (curl https://api.vultr.com/v1/regions/availability?DCID=1)"
default = 1
}
variable "vultr_plan_id" {
description = "Vultr Plan for the VPS to use (curl https://api.vultr.com/v1/plans/list)"
default = 202
}
variable "vultr_tag" {
description = "Vultr Tag to apply to the new VPS"
default = "jitsi-conference"
}
variable "vultr_app_id" {
description = "Vultr App to pre-install. This should always be '47', if jitsi is being provisioned (curl https://api.vultr.com/v1/app/list)"
default = 47
}
variable "hostname" {
description = "Hostname to be used"
default = "conferences"
}
variable "email" {
description = "email to be used for let's encrypt acme config"
default = "john.doe@email.com"
}
variable "domain" {
description = "domain to be used"
default = "aremyj.am"
}
variable "aws_access_key" {
description = "AWS Access Key - get it here: (https://console.aws.amazon.com/iam/home?#security_credential)"
}
variable "aws_secret_key" {
description = "AWS Secret Key - get it here: (https://console.aws.amazon.com/iam/home?#security_credential)"
}
variable "aws_region" {
description = "AWS Region"
default = "us-east-1"
}
|
[yourdomain].auto.tfvars
The auto.tfvars file provides values to the variables defined in the variables.tf file. You’ll have to create this file from scratch, and terraform best practices dictate that you exclude this file from source control. Here’s an example you can use. Modify this for your environment. The name doesn’t matter, as long as it ends with auto.tfvars.
1
2
3
4
5
6
7
8
9
10
11
|
vultr_api_key = "[fill this in]"
vultr_region = 1
vultr_plan_id = 202
vultr_app_id = 47
vultr_tag = "jitsi-conference"
hostname = "conference"
email = "your.email@address.org"
domain = "your-domain.com"
aws_region = "us-east-1"
aws_access_key = "[fill this in]"
aws_secret_key = "[fill this in]"
|
configure_jitsi_param.sh
Full disclosure, I did not create this script. Vultr created it, and provides it on your Jitsi VPS when you request it. Unfortunately, the version they provide is intended to be executed interactively, so I made a few very minor modifications to allow for us to run it with parameters.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
|
#!/bin/bash
#This script was copied from /opt/vultr/configure_jitsi.sh on a Vultr VPS that has the one-click Jitsi App
#I added lines 7-9 to allow for adding parameters on the CLI and commented lines 11-13 to force the variables to be provided on the CLI
#https://www.vultr.com/docs/one-click-jitsi
#https://www.virtjunkie.com/jitsi-jit-conferencing-tf-vultr-route53/
#https://github.com/jonhowe/Virtjunkie.com/tree/master/Jitsi-JIT-Conferencing-TF-Vultr-Route53
HOSTNAME=$1
EMAIL=$2
response=$3
# User choices
#read -ep "Please specify which domain you would like to use: " HOSTNAME
#read -ep "Please enter your email address for Let's Encrypt Registration: " EMAIL
#read -r -p "Would you like to enable password authorization? [y/N] " response
case "$response" in
[yY][eE][sS]|[yY])
AUTH=1
;;
*)
AUTH=0
;;
esac
PROSODYPATH=/etc/prosody/conf.avail/${HOSTNAME}.cfg.lua
JITSIPATH=/etc/jitsi/meet/${HOSTNAME}-config.js
JICOFOPATH=/etc/jitsi/jicofo/sip-communicator.properties
# Remove and purge (Stop first and wait to avoid race condition)
purgeold() {
/opt/vultr/stopjitsi.sh
sleep 5
apt -y purge jigasi jitsi-meet jitsi-meet-web-config jitsi-meet-prosody jitsi-meet-turnserver jitsi-meet-web jicofo jitsi-videobridge2 jitsi*
}
# Reinstall
reinstalljitsi() {
echo "jitsi-videobridge2 jitsi-videobridge/jvb-hostname string ${HOSTNAME}" | debconf-set-selections
echo "jitsi-meet-web-config jitsi-meet/cert-choice string Generate a new self-signed certificate (You will later get a chance to obtain a Let's encrypt certificate)" | debconf-set-selections
apt-get -y install jitsi-meet
}
# Remove nginx defaults
wipenginx() {
rm -f /etc/nginx/sites-enabled/default
}
# Configure Lets Encrypt
configssl(){
systemctl restart nginx
sed -i -e 's/echo.*Enter your email and press.*/EMAIL=$1/' /usr/share/jitsi-meet/scripts/install-letsencrypt-cert.sh
sed -i -e 's/read EMAIL//' /usr/share/jitsi-meet/scripts/install-letsencrypt-cert.sh
/usr/share/jitsi-meet/scripts/install-letsencrypt-cert.sh ${EMAIL}
}
configprosody() {
AUHTLINE='authentication = "internal_plain"'
sed -i "s/authentication\ \=\ \"anonymous\"/${AUTHLINE}/g" ${PROSODYPATH}
cat << EOT >> ${PROSODYPATH}
VirtualHost "guest.${HOSTNAME}"
authentication = "anonymous"
c2s_require_encryption = false
EOT
}
configjitsi() {
sed -i "s/\/\/\ anonymousdomain\:\ 'guest.example.com',/anonymousdomain\:\ 'guest.${HOSTNAME}',/g" ${JITSIPATH}
}
configjicofo() {
echo "org.jitsi.jicofo.auth.URL=XMPP:${HOSTNAME}" >> ${JICOFOPATH}
}
registeruser(){
PASSWORD=$(< /dev/urandom tr -dc _A-Z-a-z-0-9 | head -c${1:-16};echo;)
prosodyctl register admin ${HOSTNAME} ${PASSWORD}
}
restartjitsi() {
/opt/vultr/stopjitsi.sh
/opt/vultr/startjitsi.sh
}
completedsetup(){
echo ""
echo "------------------------------"
echo "| |"
echo "| JITSI SETUP COMPLETED! |"
echo "| |"
echo "------------------------------"
echo "JITSI URL: https://${HOSTNAME}"
echo ""
}
outputUser(){
echo "USERNAME: admin"
echo "PASSWORD: ${PASSWORD}"
echo ""
}
# Script start
purgeold
reinstalljitsi
wipenginx
configssl
if [ "$AUTH" == "1" ]; then
configprosody
configjitsi
configjicofo
registeruser
restartjitsi
fi
completedsetup
if [ "$AUTH" == "1" ]; then
outputUser
fi
|
Summary + More Reading
There you have it! With this project you can have a fully functional Jitsi instance on your own domain with end to end encryption in less than 5 minutes. When you are done, there’s no harm in deleting it so you aren’t charged.
Here are some references I used while creating this:
- https://github.com/jonhowe/Virtjunkie.com/tree/master/Jitsi-JIT-Conferencing-TF-Vultr-Route53
- https://www.vultr.com/docs/one-click-jitsi
- https://www.terraform.io/docs/providers/aws/d/route53_zone.html
- https://www.terraform.io/docs/providers/aws/r/route53_record.html
- https://www.terraform.io/docs/providers/vultr/r/server.html#default_password
- https://www.terraform.io/docs/provisioners/connection.html#the-self-object
- Create Vultr API Key: https://my.vultr.com/settings/#settingsapi
- Create AWS Access/Secret Key: https://console.aws.amazon.com/iam/home?#security_credential
- Vultr API Reference – has examples that will get you plan, region, and app IDs. https://www.vultr.com/api/