dgreif / ring

Unofficial packages for Ring Doorbells, Cameras, Alarm System, and Smart Lighting
MIT License
1.2k stars 160 forks source link

Use Ring Ice Servers #1282

Open dgreif opened 1 year ago

dgreif commented 1 year ago

Description

While looking at the new webrtc api, I noticed that the Ring web app seems to be fetching a set of ice servers when you first load the page. These values are then stored in localStorage under wrtc-isc (base64 encoded) and not fetched again.

The request is something like this:

GET https://account.ring.com/api/cmds/iceConfig

With a response like this: (note i've redacted the creds in case they are personal)

[
    {
        "IceConfiguration": [
            {
                "credential": "GTehw7**",
                "url": "turn:mrs-f63a5c68-1.p.us-west-2.cmds-tachyon.com:4172?transport=udp",
                "username": "16912**"
            },
            {
                "credential": "GTehw**",
                "url": "turns:mrs-f63a5c68-1.p.us-west-2.cmds-tachyon.com:443?transport=tcp",
                "username": "16912**"
            },
            {
                "url": "stun:mrs-f63a5c68-1.p.us-west-2.cmds-tachyon.com:4172"
            }
        ]
    }
]

We currently use a set of hard-coded STUN servers to gather ice candidates, but it would be much preferred to use these servers provided by Ring. The fact that there are turn servers in here means we may get some much better connection options for complex network scenarios (eg users on VPNs).

The biggest challenge is that the url from the web app (https://account.ring.com/api/cmds/iceConfig) does not directly translate to the url we need to use from Node.js. We need to figure out the right URL, and then it should be easy to start using the provided servers.

@tsightler maybe you have some insight here? Are the android/ios apps making similar calls to a different endpoint by chance?

tsightler commented 1 year ago

Ha, funny, I had noticed this when I was digging and noted it for further research, but at the time I was just focused on getting the code to work at all (at the time I was still tracking the immediate socket disconnect issue).

I'll fire up the app with mitmproxy and take a look sometime later tonight or tomorrow.

dgreif commented 1 year ago

Nice, glad it was on your radar already đŸ˜„. Probably not a huge deal if we don't figure it out as the existing stun servers seem to work in most scenarios. I'm guessing we end up using the ice candidates provided by the websocket connection (as part of the webrtc answer) all the time anyways, so it might not really make a difference. Just nice to match with Ring as much as possible to avoid future issues.

tsightler commented 1 year ago

Yes, that's exactly correct, the trickle ice methods implemented as part of the websocket seem to work pretty well, however, as you noted, the TURN service might explain why there are cases where the web playback will work while werift couldn't seem to make a connection. Although, admittedly, this may also be because werift appears not to support TCP candidates, which the browser will fall back to pretty quickly.

If I block all UDP for my firewall, Ring playback via the browser will still work via TCP 443 since that is one of the passed candidates, but werift will not work with this as far as I can tell, at least I've never been able to get it to work. A TURN server probably won't help this case, but it might help double NAT or other weird cases.