-
Notifications
You must be signed in to change notification settings - Fork 2
Deploying all in one XMPP STUN TURN server with containers
This document describes how to setup a server hosting XMPP, STUN/TURN services - essentially, all the services needed to bootstrap Evio overlays - using Docker containers on a cloud-hosted image.
These steps have been tested with in Amazon EC2, using the standard Ubuntu 18.04 AMI.
The setup comprises of three containers:
- evio-mysql: holds databases for the XMPP and TURN containers
- evio-openfire: runs the Openfire XMPP server
- evio-coturn: runs the coturn STUN/TURN server
These are all containers available on Dockerhub. It is assumed you have Docker installed in your system.
Ideally, you should run these on a VM that has a public IP address and a DNS name. Nonetheless, it does work with an Amazon instance without a static public IP address - we've tested it.
The firewall/security group settings of the VM hosting these services needs to be setup so the following inbound ports are open:
Custom UDP UDP 3478 0.0.0.0/0 STUN
Custom UDP UDP 49160 - 59200 0.0.0.0/0 TURN
Custom TCP TCP 5223 0.0.0.0/0 XMPP
Custom TCP TCP 9090 0.0.0.0/0 OpenFire admin
Custom TCP TCP 5222 0.0.0.0/0 XMPP
The instructions assume you are running in an EC2 instance with username ubuntu, with home directory /home/ubuntu, and its public-facing external IP address is SERVER_IP.
We'll use the convention below to denote running commands on the host vs. container, and queries within mysql:
$ a_host_command
# a_container_command
mysql> a_mysql_query
- Note: the instructions below are meant to serve as a guideline, and we do not go into best practices for setting up security, certificates, database backups, etc. The example uses a single MySQL user, and we use your_mysql_root_password to refer to a password you setup for the MySQL server.
Create a directory for your MySQL database on the host, and run the MySQL container mounting this volume:
$ mkdir mysql
$ docker run --name evio-mysql -e MYSQL_ROOT_PASSWORD=your_mysql_root_password -v /home/ubuntu/mysql:/var/lib/mysql -d mysql
Now log in to the container to create databases for openfire and turnserver:
$ docker exec -it evio-mysql bash
# mysql -u root --password=your_mysql_root_password
mysql> CREATE DATABASE openfire;
mysql> CREATE DATABASE turnserver;
mysql> \q
# exit
$
This command runs the Openfire container, and create an alias (db) to connect to the database container:
$ docker run -d -p 9090:9090 -p 5222:5222 -p 5269:5269 -p 5223:5223 -p 7443:7443 -p 7777:7777 -p 7070:7070 -p 5229:5229 -p 5275:5275 --link evio-mysql:db --name evio-openfire quantumobject/docker-openfire
Now you must manually copy the MySQL schema from the evio-openfire to your host, then copy from your host to the evio-mysql container, and load to MySQL to create the proper tables Openfire needs:
$ docker cp evio-openfire:/usr/share/openfire/resources/database/openfire_mysql.sql openfire_mysql.sql
$ docker cp openfire_mysql.sql evio-mysql:/openfire_mysql.sql
$ docker exec -it evio-mysql bash
# mysql -u root --password=your_mysql_root_password openfire < /openfire_mysql.sql
You can verify the tables have been created as follows:
# mysql -u root --password=your_mysql_root_password openfire
mysql> SHOW TABLES;
+----------------------+
| Tables_in_openfire |
+----------------------+
| ofExtComponentConf |
| ofGroup |
| ofGroupProp |
| ofGroupUser |
| ofID |
... and so on
This sequence of steps is done via page forms exposed through the Openfire admin web interface:
- Point your Web browser to: http://SERVER_IP:9090
- Select your language
- change XMPP Domain Name, Server Host Name to your server's FQDN - or, if you don't have one, use "local"
- select "Standard database connection" (which is not the default option)
- In "Pick Database": pick MySQL
- replace Database URL with the following string to connect to your other container: jdbc:mysql://db:3306/openfire
- set username: root
- set password: your_mysql_root_password
- Profile settings: Default
- Set your admin email and password for Openfire - you will use this password you need to login back again as "admin" to http://SERVER_IP:9090
If you'd like to set up Openfire to store plain passwords for users in the MySQL database (not a best practice for production deployments, but makes the process easier for testing), log into the evio-mysql container and set this property:
$ docker exec -it evio-mysql bash
# mysql -u root --password=your_mysql_root_password openfire
mysql> INSERT INTO ofProperty (name, propValue) VALUES ('user.usePlainPassword','true');
mysql> \q
# exit
$
First, create a directory on your host to hold the configuration file for the coturn container, and create the configuration file turnserver.conf:
$ cd
$ mkdir coturn
$ cd coturn
$ vi turnserver.conf
There are many configuration options for coturn, but the template turnserver.conf below will get you started. You must replace three items in this template
realm=local
fingerprint
external-ip=SERVER_IP
listening-port=3478
min-port=49160
max-port=59200
lt-cred-mech
mysql-userdb="host=MYSQL_CONTAINER_IP dbname=turnserver user=root password=your_mysql_root_password connect_timeout=30 read_timeout=30”
- Make sure you replace SERVER_IP with the address of your server!!
- Make sure you replace your_mysql_root_password!!
- Replace MYSQL_CONTAINER_IP with the IP address of your evio-mysql container. This is a private address, and you can determine it as follows:
$ docker inspect evio-mysql | grep IPAddress
Now you're run the evio-coturn container - note that it binds to the host network, since it uses many ports for relaying:
$ docker run -d --network=host --name evio-coturn -v /home/ubuntu/coturn/turnserver.conf:/etc/coturn/turnserver.conf instrumentisto/coturn -c /etc/coturn/turnserver.conf
Now you must manually copy the MySQL schema from the evio-coturn container to your host, then copy from your host to the evio-mysql container, and load to MySQL to create the proper tables the coturn TURN server needs:
$ docker cp evio-coturn:/usr/share/turnserver/schema.sql turnserver.sql
$ docker cp turnserver.sql evio-mysql:/turnserver.sql
$ docker exec -it evio-coturn sh
# mysql -u root --password=your_mysql_root_password turnserver < /turnserver.sql
You're done with the basic installation steps! Now you're ready to add users.
The Evio team is developing scripts that will help in the creation of users in XMPP, TURN, as well as Evio configuration files. We'll add to this page as we progress.
If you want to manually create XMPP users/groups, the SQL commands you need to use follow this template (assuming you are using plain passwords):
INSERT INTO ofUser (username, email, iterations, plainPassword, creationDate, modificationDate) VALUES ('node1', 'someone@email.com', 4096, 'some_password_1'
, 1599071130973, 1599071130973);
INSERT INTO ofUser (username, email, iterations, plainPassword, creationDate, modificationDate) VALUES ('node2', 'someone@email.com', 4096, 'some_password_2'
, 1599071130973, 1599071130973);
INSERT INTO ofUser (username, email, iterations, plainPassword, creationDate, modificationDate) VALUES ('node3', 'someone@email.com', 4096, 'some_password_3'
, 1599071130973, 1599071130973);
INSERT INTO ofGroup (groupName) VALUES ('mygroup');
INSERT INTO ofGroupUser (groupName, username, administrator) VALUES ('mygroup', 'node1', 0);
INSERT INTO ofGroupUser (groupName, username, administrator) VALUES ('mygroup', 'node2', 0);
INSERT INTO ofGroupUser (groupName, username, administrator) VALUES ('mygroup', 'node3', 0);
INSERT INTO ofGroupProp (groupName, name, propValue) VALUES ('mygroup', 'sharedRoster.displayName', 'mygroup');
INSERT INTO ofGroupProp (groupName, name, propValue) VALUES ('mygroup', 'sharedRoster.groupList', '');
INSERT INTO ofGroupProp (groupName, name, propValue) VALUES ('mygroup', 'sharedRoster.showInRoster', 'onlyGroup');
And for TURN users, you can use the turnadmin program that's available within evio-coturn (replace 172.17.0.2 with the evio-mysql container's IP):
$ docker exec -it evio-coturn sh
# turnadmin --mysql-userdb "host=172.17.0.2 dbname=turnserver user=root password=your_mysql_root_password connect_timeout=30 read_timeout=30" -a -r local -u node1 -p some_password_1
# turnadmin --mysql-userdb "host=172.17.0.2 dbname=turnserver user=root password=your_mysql_root_password connect_timeout=30 read_timeout=30" -a -r local -u node2 -p some_password_2
# turnadmin --mysql-userdb "host=172.17.0.2 dbname=turnserver user=root password=your_mysql_root_password connect_timeout=30 read_timeout=30" -a -r local -u node3 -p some_password_3