silvio / docker-matrix

docker image for matrix.org
GNU General Public License v2.0
142 stars 76 forks source link

VoIP with TURN does not work without host networking #38

Open djmaze opened 6 years ago

djmaze commented 6 years ago

Does anyone have VoIP calling working when just exposing ports? In order for NATted clients to be able to do voice/video calls, I have to switch to host networking for the container.

mvgorcum commented 6 years ago

STUN worked for me using only ports 3478, 5349 forwarded to the container, but this only worked for a few simple NATed clients. You can test your server here if you want.

To actually use TURN (in my case mostly for clients using their mobile data) I had to also forward the udp port-range mentioned in the readme (both to the container and since my server is behind a NAT as well, also in the router. Which meant I also had to add the external IP). You could look at the console log of riot to try and figure out what goes wrong when trying to set up the webrtc instance.

djmaze commented 6 years ago

Okay, to be honest, I had to switch to host networking because I am using docker swarm mode. Which has massive problems forwarding big port ranges.

So at first I tried forwarding only a few ports and adjusting the min-port/max-port range in the coturn configuration. With two NATted clients, they still couldn't connect to each other. Why, I am not sure. Maybe should try the test service you mentioned, thanks!

So I finally made coturn an independent container and switched it to host networking. Will publish the working setup soon (after some cleanup).

mvgorcum commented 6 years ago

I never used docker swarm, so I can't comment on that. I did reduce the port range with min-port and max-port in turnserver.conf (I think I 'only' forward a couple of hundred ports) which seems to work fine. IIRC the console log of riot should show which port it is trying to use when using TURN.

Splitting off coturn in a separate container sounds like a good solution to me, though.

emcgee commented 6 years ago

@djmaze Just as an FYI, if you want to use the standard Swarm ingress network and work around the inability of Docker to use ranges in iptables, you can run the following on any node that runs your matrix/coturn server after the container has started:

CIP=$(sudo docker inspect --format='{{.NetworkSettings.IPAddress}}' $CID)

sudo iptables -A DOCKER -t nat -p udp -m udp ! -i docker0 --dport 49152:65535 -j DNAT --to-destination $CIP: 49152-65535
sudo iptables -A DOCKER -p udp -m udp -d $CIP/32 ! -i docker0 -o docker0 --dport 49152:65535 -j ACCEPT
sudo iptables -A POSTROUTING -t nat -p udp -m udp -s $CIP/32 -d $CIP/32 --dport 49152:65535 -j MASQUERADE

Alternatively, you could keep your coturn container in the standard Swarm stack file and setup a host network in the yaml -- this'll run host mode on whatever node coturn is scheduled but allows you to keep it fully integrated with your Swarm

e.g.


service:
  coturn:
    image: matrix:conturn
    networks:
       - my_host_network

networks:
  my_host_network:
    external:
      name: 'host'
djmaze commented 6 years ago

@emcgee The second approach is the one I went with. It is, while rather ugly, even possible to use this existing image for that:

services:
  synapse:
    image: silviof/docker-matrix:latest
    networks:
      - backend
      - frontend
    volumes:
      - /srv/matrix-server:/data
    ports:
      - 8448:8448/tcp
    […]

  turnserver:
    image: silviof/docker-matrix:latest
    networks:
      - host
    volumes:
      - /srv/matrix-turnserver:/data
    […]

The directory /srv/matrix-server contains the homeserver.yml while /srv/matrix-turnserver contains the turnserver.conf.

andreaspeters commented 6 years ago

@djmaze, u still have trouble with it? if yes, we will try to investigate.

djmaze commented 6 years ago

@andreaspeters Still using the approach outlined above, and it works quite well.

I'd rather have a clean separation with two separate docker images. Didn't find the time to dive into that yet though.

andreaspeters commented 6 years ago

@djmaze me too. :-) actually we use it also separate in our production system. In a future release, there will be a variable with that u can control the services u want to run inside of the container.