go2rtc icon indicating copy to clipboard operation
go2rtc copied to clipboard

Issue with network topology involving VPN and 2 sites

Open J-Prince opened this issue 2 years ago • 20 comments

Hello,

I am having issues with WebRTC protocol in my particular network topology involving 2 sites connected via VPN.

My setup:

Site1 Docker server running Frigate 0.12 rc2

2023-04-04 12:11:33.629540773  [INFO] Preparing go2rtc config...
2023-04-04 12:11:33.719847311  [INFO] Not injecting WebRTC candidates into go2rtc config as it has been set manually
2023-04-04 12:11:33.733325568  [INFO] Starting go2rtc...
2023-04-04 12:11:33.801569519  12:11:33.800 INF go2rtc version 1.2.0 linux/amd64
2023-04-04 12:11:33.801572791  12:11:33.801 INF [api] listen addr=:1984
2023-04-04 12:11:33.801576488  12:11:33.801 INF [rtsp] listen addr=:8554
2023-04-04 12:11:33.801578018  12:11:33.801 INF [srtp] listen addr=:8443
2023-04-04 12:11:33.801579341  12:11:33.801 INF [webrtc] listen addr=:8555
2023-04-04 12:11:43.630126325  [INFO] Starting go2rtc healthcheck service...

Site1 is connected to Site2 via Wireguard VPN.

On Site2, unable to start a webrtc session in Safari, iPhone.

tcpdump shows the data flowing freely, in both directions, and non-stop on UDP port 8555 between the Frigate server in Site1 and the device in Site2. However, the video never loads which is quite puzzling.

There is no NAT to deal with, all IPs are reachable directly between Site1 and Site2.

I have the following setup in Frigate:

go2rtc:
  streams:
    Cam1:
      - rtsp://user:[email protected]:554/Streaming/Channels/101
    Cam2:
      - rtsp://user:[email protected]:554/Streaming/Channels/101
  webrtc:
    candidates:
      - 172.17.0.2:8555  # docker image internal IP
      - 10.10.10.10:8555  # docker host

Would it be possible to tell go2rtc to NOT try to use any STUN or TURN server, since the connection should work internally. Maybe adding "local" subnets in the go2rtc configuration?

Even without Frigate in the equation, for example using the "stream.html WebRTC stream" link from the go2rtc page, same result.

Thank you!

J-Prince avatar Apr 04 '23 16:04 J-Prince

I'm having the same issue. Using Frigate. Site to Site VPN using Wireguard on the routers. In Wireshark I see a constant stream of UDP traffic coming from the server on port 8555. But the video player just remains at loading.

sovapatr avatar Apr 11 '23 14:04 sovapatr

What viewers (html) have your tried? What about Frigate 12 release?

AlexxIT avatar Apr 14 '23 04:04 AlexxIT

I'm using Frigate 0.12.0-DA3E197. Trying to access the stream from the /live/webrtc/links.html?src=backyard page. I've tried in both Chrome and Firefox if that is what you mean for viewers. stream.html?src=backyard&mode=mse works while at the second site. But mode=webrtc only seems to work when my laptop is on the same network as the server.

sovapatr avatar Apr 14 '23 13:04 sovapatr

Current version: 1.5.0

Hey,

I have this problem too.

All my networking is internal (ie, the viewers and go2rtc are on different sites connected by wireguard at their respective routers). The moment I fire a stream (I'm using the webrtc-camera card), I see dozens of public ip-to-public ip UDP requests between the two routers (from the router behind which go2rtc is to the router behind which the viewer is), and this triggers the destination router's port scan alarm and ultimately blocks the originating router's ip.

Now, I can either a) whitelist the originating router's IP (which is a PITA, because it's dynamic and has I'd have to script out something) or b) disable port scanning altogether, but since both go2rtc and the viewer's host are directly reachable (through their private IPs) and I have no intention to make the cameras available on the internet, I am looking for a way to, somehow, instruct go2rtc to just use private IPs and therefore avoid the whole STUN situation altogether - because it's ultimately not necessary.

I've added

webrtc:
  listen: ":8555"
  candidates:
   - 192.168.38.209:8555

to the go2rtc.yml config file, but that didn't alter this behaviour. I fully admit I don't understand these config params deeply (or the protocols in question, for that matter) but I was wondering if there's a way to keep everything flowing through the private IPs.

Thanks

gedl avatar Jun 16 '23 16:06 gedl

Basic docker users (also Frigate docker users) shouldn't have any problems with LAN connections. And shouldn't add any local IP to go2rtc config. They should use docker network host option. And they will be fine.

Frigate addon users should proxy WebRTC port and set local candidate IP manually. Because they can't use network host.

AlexxIT avatar Jun 16 '23 18:06 AlexxIT

Hey AlexxIT

I'm running the go2rtc server in an LCX container in a proxmox host, on bridged mode.

Do you have any recommendations to stop go2rtc from going the STUN route ?

gedl avatar Jun 16 '23 20:06 gedl

@gedl do you have problems with local or with external connections?

AlexxIT avatar Jun 17 '23 03:06 AlexxIT

Hi @AlexxIT

I don't expose the cameras externally at all - there is no domain name (or route, for that matter) into the go2rtc box. The STUN kicks in for internal to internal network requests, like so:

192.168.37.7 (browser) -> 192.168.37.1 / 192.168.138.1 (router 1 Lan/Wg) ---> internet ---> 192.168.38.1 / 192.168.138.2 (router 2 Lan/wg) -> 192.168.38.5 (proxmox) -> 192.168.38.115 (go2rtc).

Right when I open the webrtc card in homeassistant, the go2rtc fires a lot of UDP packets to router 2's public IP, instead of simply using the readily available private network path.

The network hosts on either side of the internet have open-bar access to each others, on all ports.

gedl avatar Jun 17 '23 09:06 gedl

WebRTC (in the browser and in the go2rtc) will try all possible ways to connect. Because they don't know which is the best route.

AlexxIT avatar Jun 17 '23 10:06 AlexxIT

I understand that. I guess what @J-Prince and I are asking is if there's a way to instruct either party (but particularly go2rtc) to use a specific route, or to disable STUN altogether and skip straight to the next alternative (until eventually settles on using the internal, direct route between the hosts).

gedl avatar Jun 17 '23 12:06 gedl

You can disable STUN in the go2rtc yaml. Just use empty ice servers list.

AlexxIT avatar Jun 17 '23 14:06 AlexxIT

Maybe I'm after a red herring with the STUN remark, but with

webrtc:
  ice_servers: []

I still see a blast of UDP connections from one router's public IP (the one behind which go2rtc runs) to the other router's public IP (behind which the browser is). These two hosts are directly reachable through private IPs, and my goal was to make them do so rather than trying to punch UDP holes on the each other's firewalls.

This is what tcpdump shows when the page loads

23:09:13.280426 IP 18x.58.xxx.xx3.15543 > 2xx.187.xxx.xx0.53805: UDP, length 100
23:09:13.280813 IP 18x.58.xxx.xx3.15543 > 2xx.187.xxx.xx0.61214: UDP, length 100
23:09:13.281087 IP 18x.58.xxx.xx3.15543 > 2xx.187.xxx.xx0.53805: UDP, length 100
23:09:13.281302 IP 18x.58.xxx.xx3.15543 > 2xx.187.xxx.xx0.61214: UDP, length 100
23:09:13.291919 IP 18x.58.xxx.xx3.15543 > 2xx.187.xxx.xx0.53805: UDP, length 100
23:09:13.292146 IP 18x.58.xxx.xx3.15543 > 2xx.187.xxx.xx0.61214: UDP, length 100

gedl avatar Jun 17 '23 22:06 gedl

Browser still has ice settings. You can be changed only with JS code. No any settings for that. But it shouldn't be a problem.

AlexxIT avatar Jun 18 '23 16:06 AlexxIT

But the IP blasting the requests is go2rtc's router, not the browser's.

I agree there shouldn't be any problem in the general case. In my particular case this is identified as a port scan (about 50 connections within 2 seconds).

Totally understand if this is a niche situation that doesn't warrant a generally available setting to avoid, but since it is go2rtc's side blasting the browser's side, I was hoping there would be a setting there for it just not to.

gedl avatar Jun 18 '23 19:06 gedl

You can enable trace log level for webrtc module and check all local and remote candidates there

AlexxIT avatar Jun 19 '23 07:06 AlexxIT

I have the same problem. Has anyone found a solution? @gedl @J-Prince @sovapatr The two subnets are directly connected with wireguard, freely passable, yet webrtc cannot pass through.

I created an EOIP tunnel, the client got the ip address directly from the server subnet, but still it was not able to establish the connection. I haven't got around to tracing my connections yet.

gleanlux avatar Sep 11 '23 15:09 gleanlux

I have the same problem. Has anyone found a solution? @gedl @J-Prince @sovapatr The two subnets are directly connected with wireguard, freely passable, yet webrtc cannot pass through.

Unfortunately no. I have to resort to use jsmpeg for Frigate live view, which less than ideal.

J-Prince avatar Sep 11 '23 15:09 J-Prince

I started testing the problem from many directions and came to the following conclusions:

  • Even though I created an EOIP tunnel between the two subnets, and my laptop received an IP directly from my home network, the webrtc still did not work.
  • I monitored the server side, client side, and the two routers: the go2rtc, after failing to reach the internet, finds its way to the internal network, but sends UDP packets in vain, no video connection is established.

The most interesting observation:

  • My home network is sent out to the garage with wifi, two antennas, and then a wifi AP is in place. It's exactly the same network as the one inside, just bridge-connected. Despite this, WEBRTC DOES NOT WORK in the garage either!!!

Could there be any connection between WEBRTC and the jump points? Because we can clearly state that we are not talking about an IP fault here. @AlexxIT Please help us to investigate the error so we can find a solution. Any way I can help you to solve it.

gleanlux avatar Sep 13 '23 07:09 gleanlux

I think it's hard task for really hi level network engineers to build solid local routing between multiple local subnets. There is no magic here. Two clients are exchanging IP addresses. And both are trying to reach each other. They can or can't do it. Based on your internal routing.

AlexxIT avatar Sep 13 '23 10:09 AlexxIT

@gedl Did you find a solution to your problem?

barzag avatar Sep 12 '24 14:09 barzag