├── .gitignore ├── Dockerfile ├── README.md ├── coturn.logrotate ├── coturn.sh ├── data ├── .placeholder └── config.example └── scripts ├── turnserver-container.service └── turnserver-container.upstart /.gitignore: -------------------------------------------------------------------------------- 1 | data/config 2 | data/turnserver 3 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | # Coturn TURN server in Docker 2 | # 3 | # This Dockerfile creates a container which runs a Coturn TURN server suitable 4 | # for use with Spreed WebRTC. 5 | # 6 | # Install Docker and then run `docker build -t docker-webrtc-turnserver .` to 7 | # build the image. 8 | # 9 | # Due to the nature of TURN, the container needs to use the hosts network. To 10 | # configure the details, create the config file `data/config`. See the example 11 | # in `data/config.example` for some ideas. 12 | # ``` 13 | # 14 | # Afterwards run the container like this: 15 | # 16 | # ``` 17 | # docker run --rm --net=host --name my-spreed-turnserver -i -v `pwd`/data:/srv -t spreed-turnserver 18 | # ``` 19 | # 20 | # This runs the container with the settings as defined in the config file which is # made available to the container using the volume (-v) option. This volume is also 21 | # used as storage for persistent data created by the TURN server. 22 | 23 | FROM phusion/baseimage:0.9.19 24 | MAINTAINER Simon Eisenmann 25 | 26 | # Set locale. 27 | RUN locale-gen --no-purge en_US.UTF-8 28 | ENV LC_ALL en_US.UTF-8 29 | 30 | ENV DEBIAN_FRONTEND noninteractive 31 | 32 | # Use baseimage-docker's init system. 33 | CMD ["/sbin/my_init"] 34 | 35 | # Install coturn. 36 | RUN apt-get update && apt-get -y install \ 37 | coturn 38 | RUN mkdir /etc/service/coturn 39 | ADD coturn.sh /etc/service/coturn/run 40 | ADD coturn.logrotate /etc/logrotate.d/coturn 41 | 42 | # Fix logrotate. 43 | RUN sed -i 's/su root syslog/su root adm/g' /etc/logrotate.conf 44 | 45 | # Get rid of sshd. 46 | RUN rm -rf /etc/service/sshd && rm -f /etc/my_init.d/00_regen_ssh_host_keys.sh 47 | 48 | # Allow volume. 49 | VOLUME /srv 50 | 51 | # Clean up APT when done. 52 | RUN apt-get clean && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* 53 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Docker image for Coturn suitable for WebRTC 2 | 3 | This Docker repository provides the [Coturn](https://github.com/coturn/coturn) TURN server with a configuration suitable to use with [Spreed WebRTC](https://github.com/strukturag/spreed-webrtc). 4 | 5 | ## Build Docker image 6 | 7 | Install Docker and then run `docker build -t docker-webrtc-turnserver .` to build the image. 8 | 9 | ## TURN server configuration for WebRTC 10 | 11 | To get the best out of TURN it is required to have two different routable IP addresses, you can run it with one but will loose [RFC-5780](https://tools.ietf.org/html/rfc5780) support. 12 | 13 | Also the TURN server supports TLS encryption for TURN and STUN requests. This is optional and not required. Not encrypting TURN and STUN does leak end-point information to the wire but the WebRTC connection going through TURN is still end-to-end encrypted, no matter if TURN/STUN is encrypted or not. If you choose to use TURN with TLS make sure to provide a certificate including the full chain and configure the TURN hostnames to match what is in the certificate as normal certificate validation is done. Also note that TURN with TLS is currently [not supported by Firefox](https://bugzilla.mozilla.org/show_bug.cgi?id=1056934) - so make sure to include turns: and turn: endpoints in the configuration. The TURN server supports all enabled protocols on all ports. 14 | 15 | Furthermore, to get best firewall traversal it is recommended to let the TURN server listen on port 443 and solely use that port in client configurations. 16 | 17 | Due to the nature of TURN, the container needs to use the hosts network. To configure the details, create the config file `data/config` like this minimal example: 18 | 19 | ``` 20 | LISTENING_PORT=443 21 | ALT_LISTENING_PORT=3478 22 | LISTEN_IPS="##FIRST_IP## ##SECOND_IP##" 23 | RELAY_IP=##FIRST_IP## 24 | STATIC_AUTH_SECRET=##SECRET## 25 | REALM=myturnserver 26 | VERBOSE=1 27 | ``` 28 | 29 | Of course replace the ##placeholders## with the appropriate values. Also as we are using host networking, make sure the IPs you use here are actually configured and up. 30 | 31 | There are many more configuration settings. See `data/config.example` for a full production ready example. For the whole list see the `coturn.sh` script. 32 | 33 | 34 | ## Run TURN server Docker image 35 | 36 | ``` 37 | docker run --rm --net=host --name my-webrtc-turnserver -i -v `pwd`/data:/srv -t docker-webrtc-turnserver 38 | ``` 39 | 40 | This runs the container with the settings as defined in the `config` file which is made available to the container using the volume (-v) option. This volume is also used as storage for persistent data created by the TURN server. 41 | 42 | 43 | ## Spreed WebRTC integration 44 | 45 | When the TURN server is running, make sure you have set `STATIC_AUTH_SECRET` in the `config` file. That is the value you need to use as `turnSecret` in the Spreed WebRTC `server.conf`. Last do not forget to also set `turnURIs` to point to your TURN servers end points and provided protocols. 46 | 47 | ``` 48 | turnSecret = ##SECRET## 49 | turnURIs = turn:##FIRST_IP##:443?transport=udp turn:##FIRST_IP##:443?transport=tcp 50 | ``` 51 | 52 | Or, if you have configured TLS for TURN: 53 | 54 | ``` 55 | turnSecret = ##SECRET## 56 | turnURIs = turns:##FQDN##:443?transport=udp turns:##FQDN##:443?transport=tcp turn:##FQDN##:443?transport=udp turn:##FQDN##:443?transport=tcp 57 | ``` 58 | 59 | Of course you can always use the full qualified domain name (##FQDN##) if you have it (DNS configuration) but it is only mandatory for TURN/STUN with TLS. 60 | 61 | And last, you can disable the `stunURIs` setting, as the TURN server will also provide STUN automatically. 62 | 63 | Do not forget to restart Spreed WebRTC and to reload the Web client to receive new TURN credentials. 64 | 65 | -------------------------------------------------------------------------------- /coturn.logrotate: -------------------------------------------------------------------------------- 1 | /srv/turnserver/turnserver.log { 2 | rotate 12 3 | monthly 4 | compress 5 | delaycompress 6 | notifempty 7 | copytruncate 8 | missingok 9 | postrotate 10 | /bin/kill -HUP `cat /var/run/turnserver.pid 2>/dev/null` 2> /dev/null || true 11 | endscript 12 | } 13 | -------------------------------------------------------------------------------- /coturn.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -e 3 | 4 | ARGS=() 5 | 6 | mkdir -p /srv/turnserver 7 | chown root.root /srv/turnserver 8 | chmod 755 /srv/turnserver 9 | 10 | if [ -e "/srv/config" ]; then 11 | . /srv/config 12 | fi 13 | 14 | if [ -z "$LISTENING_PORT" ]; then 15 | LISTENING_PORT="3478" 16 | fi 17 | 18 | if [ -z "$TLS_LISTENING_PORT" ]; then 19 | TLS_LISTENING_PORT="5349" 20 | fi 21 | 22 | if [ -z "$ALT_LISTENING_PORT" ]; then 23 | ALT_LISTENING_PORT="3479" 24 | fi 25 | 26 | if [ -z "$ALT_TLS_LISTENING_PORT" ]; then 27 | ALT_TLS_LISTENING_PORT="5350" 28 | fi 29 | 30 | for ip in $LISTEN_IPS; do 31 | ARGS+=" -L $ip" 32 | done 33 | 34 | for ip in $EXTERNAL_IPS; do 35 | ARGS+=" -X $ip" 36 | done 37 | 38 | ARGS+=" --listening-port=$LISTENING_PORT" 39 | ARGS+=" --tls-listening-port=$TLS_LISTENING_PORT" 40 | ARGS+=" --alt-listening-port=$ALT_LISTENING_PORT" 41 | ARGS+=" --alt-tls-listening-port=$ALT_TLS_LISTENING_PORT" 42 | 43 | if [ -n "$TLS_CERT" ]; then 44 | ARGS+=" --cert=$TLS_CERT" 45 | fi 46 | 47 | if [ -n "$TLS_KEY" ]; then 48 | ARGS+=" --pkey=$TLS_KEY" 49 | fi 50 | 51 | if [ -n "$DH_FILE" ]; then 52 | ARGS+=" --dh-file=$DH_FILE" 53 | fi 54 | 55 | if [ -n "$RELAY_IP" ]; then 56 | ARGS+=" --relay-ip=$RELAY_IP" 57 | fi 58 | 59 | if [ -n "$STATIC_AUTH_SECRET" ]; then 60 | ARGS+=" --lt-cred-mech --use-auth-secret --static-auth-secret=$STATIC_AUTH_SECRET" 61 | fi 62 | 63 | if [ -n "$RELAY_THREADS" ]; then 64 | ARGS+=" --relay-threads=$RELAY_THREADS" 65 | fi 66 | 67 | if [ -n "$NO_AUTH" ]; then 68 | ARGS+=" --no-auth" 69 | fi 70 | 71 | if [ "$VERBOSE" = "1" ]; then 72 | ARGS+=" --verbose" 73 | fi 74 | 75 | if [ "$DEBUG" = "1" ]; then 76 | ARGS+=" --Verbose" 77 | fi 78 | 79 | if [ -n "$REDIS_STATSDB" ]; then 80 | # Use like REDIS_STATSDB=mydb password=secret, and link with redis container, named redis. 81 | ARGS+=" --redis-statsdb=host=$REDIS_PORT_6379_TCP_ADDR dbname=$REDIS_STATSDB port=$REDIS_PORT_6379_TCP_PORT connect_timeout=30" 82 | fi 83 | 84 | if [ -z "$CIPHER_LIST" ]; then 85 | CIPHER_LIST="ECDH+AESGCM:DH+AESGCM:ECDH+AES256:DH+AES256:ECDH+AES128:DH+AES:ECDH+3DES:DH+3DES:RSA+AES:RSA+3DES:!ADH:!AECDH:!MD5" 86 | fi 87 | 88 | if [ -z "$REALM" ]; then 89 | REALM="localdomain" 90 | fi 91 | 92 | if [ -z "$MIN_PORT"]; then 93 | MIN_PORT="49152" 94 | fi 95 | 96 | if [ -z "$MAX_PORT" ]; then 97 | MAX_PORT="65535" 98 | fi 99 | 100 | if [ -z "$MAX_BPS" ]; then 101 | MAX_BPS="640000" # 5 Mbit/second per TURN session 102 | fi 103 | 104 | if [ -z "$BPS_CAPACITY" ]; then 105 | BPS_CAPACITY="6400000" # 50 Mbit/second 106 | fi 107 | 108 | if [ -z "$USER_QUOTA" ]; then 109 | USER_QUOTA=100 110 | fi 111 | 112 | if [ -z "$TOTAL_QUOTA" ]; then 113 | TOTAL_QUOTA=300 114 | fi 115 | 116 | if [ -z "$USER_DB" ]; then 117 | USER_DB="/srv/turnserver/turndb" 118 | fi 119 | 120 | if [ -z "$LOG_FILE" ]; then 121 | LOG_FILE="syslog" 122 | fi 123 | 124 | 125 | sleep 2 126 | exec /usr/bin/turnserver \ 127 | -n \ 128 | ${ARGS[@]} \ 129 | --no-cli \ 130 | --log-file=$LOG_FILE \ 131 | --no-stdout-log \ 132 | --simple-log \ 133 | --fingerprint \ 134 | --dh2066 \ 135 | --realm=$REALM \ 136 | --stale-nonce \ 137 | --check-origin-consistency \ 138 | --no-loopback-peers \ 139 | --no-multicast-peers \ 140 | --min-port=$MIN_PORT \ 141 | --max-port=$MAX_PORT \ 142 | --max-bps=$MAX_BPS \ 143 | --bps-capacity=$BPS_CAPACITY \ 144 | --cipher-list=$CIPHER_LIST \ 145 | --userdb=$USER_DB \ 146 | --user-quota=$USER_QUOTA \ 147 | --total-quota=$TOTAL_QUOTA 148 | -------------------------------------------------------------------------------- /data/.placeholder: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/strukturag/docker-webrtc-turnserver/48e7b0009fa0926809929b7ea573a5b79de60368/data/.placeholder -------------------------------------------------------------------------------- /data/config.example: -------------------------------------------------------------------------------- 1 | LISTENING_PORT=443 2 | TLS_LISTENING_PORT=443 3 | ALT_LISTENING_PORT=3478 4 | ALT_TLS_LISTENING_PORT=3478 5 | 6 | LISTEN_IPS="##FIRST_IP## ##SECOND_IP##" 7 | 8 | TLS_CERT=/srv/turnserver.crt 9 | TLS_KEY=/srv/turnserver.key 10 | 11 | RELAY_IP=##FIRST_IP## 12 | 13 | STATIC_AUTH_SECRET=##SECRET## 14 | 15 | REALM=myturnserver 16 | 17 | VERBOSE=1 18 | LOG_FILE=/srv/turnserver.log 19 | 20 | -------------------------------------------------------------------------------- /scripts/turnserver-container.service: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=WebRTC TURNserver container 3 | After=docker.service 4 | Requires=docker.service 5 | 6 | [Service] 7 | Environment=NAME=webrtc-turnserver 8 | Environment=VERSION=latest 9 | Environment=FOLDER=/srv/webrtc-turnserver 10 | Restart=always 11 | ExecStartPre=-/usr/bin/docker rm ${NAME} 12 | ExecStart=/usr/bin/docker run \ 13 | --rm=true \ 14 | --net=host \ 15 | -v=${FOLDER}:/srv \ 16 | --name=${NAME} \ 17 | -t spreed/turnserver:${VERSION} 18 | ExecStop=-/usr/bin/docker stop ${NAME} 19 | 20 | [Install] 21 | WantedBy=default.target 22 | -------------------------------------------------------------------------------- /scripts/turnserver-container.upstart: -------------------------------------------------------------------------------- 1 | description "WebRTC TURNserver container" 2 | author "Simon Eisenmann " 3 | 4 | start on filesystem and started docker 5 | stop on stopping docker 6 | 7 | respawn 8 | 9 | env NAME=webrtc-turnserver 10 | env VERSION=latest 11 | env FOLDER=/srv/webrtc-turnserver 12 | 13 | pre-start script 14 | docker rm $NAME >/dev/null 2>&1 || true 15 | end script 16 | 17 | script 18 | exec docker run \ 19 | --rm=true \ 20 | --net=host \ 21 | -v=$FOLDER:/srv \ 22 | --name=$NAME \ 23 | -t spreed/turnserver:$VERSION 24 | end script 25 | 26 | post-stop script 27 | exec docker stop $NAME || true 28 | end script 29 | --------------------------------------------------------------------------------