tchellomello/python-arlo

View RTMPS live stream access

Opened this issue · 36 comments

cam_object.live_streaming() provides the live stream which is returned as type rtmps://. This would indicate that it is an encrypted RTMP stream.

At this point, I haven't seen anyone successfully open the stream. I have tried to stream with ffmpeg however received errors of various types.

I suspect either a certificate is required, or some token is needed to access/decrypt the stream.

I spent a little time on this yesterday. I install Android x86 and installed the Arlo app within the VM.

However when trying to launch the Arlo app, it crashes instantly. Everything else appears to work on in the VM, so I'm a little uncertain on why this decided to fail. Will take another look tonight.

The second thing I noticed, while poking around in the Android APK, is that there are libraries for ffmpeg, x264. There is also a wowza certificate in the assets folder.

So hopefully they aren't doing anything funky and these libraries are all that's needed to decode the stream.

I did some inspection using Fiddler as a proxy for my phone while running the Android app and opening a live stream. The things you noted above are correct. There is a wowza secure stream player used. There are also 2 certs I noted in the trace. One was a Netgear Arlo cert. The other was an Amazon AWS cert. The stream is tunneled from AWS.

I believe this is the documentation outlined the server side encrpytion:
https://www.wowza.com/docs/how-to-protect-rtmp-streaming-using-securetoken-modulesecuretoken

So I believe the web interface and likely the android app are using a flash player to stream. Seeing as flash isn't possible on the apple devices, I'm wondering if they are using a different stream protocol instead.

If so, this might be an easier way to access the live stream.

I have an apple device and tried to use fiddler to view what was going on, but when I turn on https decryption, I get certificate errors on the device.

By changing the user agent string to "Mozilla/5.0 (iPhone; CPU iPhone OS 9_3_5 like Mac OS X) AppleWebKit/601.1.46 (KHTML, like Gecko) Mobile/13G36 NETGEAR/v1 (iOS Vuezone)",

I get the following stream response:
"rtsp://52.38.114.182:443/vzmodulelive/<useid_cameraid>?egressToken=&userAgent=iOS&cameraId=<camera_id>"

So yes as I suspected, the iOS is using a different stream format (Android is possibly using this as well). I haven't successfully managed to stream this yet with ffmpeg, but will give it a try later tonight.

I poked around with this the other night, mostly trying to play the RTSP stream with no success. I was able to connect to the rtsp server with openssl and validate that it did provide a correct certificate.

I also decided to snoop on the traffic from the camera itself, however it appears that the camera initiates all traffic, and its SSL encrypted.

Still want to investigate more, trying to understand how the netgear servers initiates camera requests. It appears that the camera keeps the encrypted connection constantly open, and this is used, however this seems a bit weird. Once I figure out how to do an SSL man in the middle attack with my setup I will post some results.

You are definitely onto something. I'm on a hotel network that seemingly does throttling / dropping of video connections. Whenever I try to connect to my live camera feeds through a web browser, the feed gets disconnected. However, if I use the Android app on the hotel network, it connects and streams no problem. Obviously something wonky about how the hotel filters connections, but it at least confirms that there is a distinct difference in how the site and apps are streaming. This is foreign territory for me, though.

Foreign for me as well, been a crash course of hacking my network :) I have an android device which I will take home and have a look at what that is doing. I suspect it's probably using the same rtsp stream that the ios devices are using.

I will try and read up more on the wowza documentation on RTSP streaming, hopefully this will have some key on what I should be doing.

This is awesome guys

Any updates? I've been attempting to start the stream via librtmp unfortunately I keep getting a failure to start the stream. It does get connected however.


import librtmp

rtmp = librtmp.RTMP(url=camurl, token=arlo._PyArlo__token, live=True)
rtmp.connect()

stream = rtmp.create_stream()
data = stream.read(1024)

rtmp.close()

This is a secured stream, so I don't think it will be possible without the appropriate certificate.

My first goal is updating the thumbnail on the website and on the mobile app. So, I think that if i can manage to get the stream online (not actually decode it) for a second or so, that will happen. Merely getting the url almost does it.

I've also tried the following which downloads their player. Though I suspect the reason this doesn't work is that they also load a flowplayer rtmp plugin.


import librtmp

rtmp = librtmp.RTMP(url=url,
                    token=arlo._PyArlo__token,
                    swfurl="https://arlo.netgear.com/flowplayer/flowplayer.commercial.swf",
                    live=True)
rtmp.connect()

stream = rtmp.create_stream()
data = stream.read(1024)

rtmp.close()

Has anyone dug into the flashvars? They look interesting to say the least. I suspect the token field contained in those is what we need.

Seems that flashvars references to the plugins used to securely stream to the client. I've been attempting to find if python-librtmp has a feature to do this; so far, it doesn't appear so.

I would also like to know if anyone has made any further progress here. Overall I am pretty happy with my arlo cameras, but having access to the live stream wherever I want it would be huge. I have played around and gotten about as far as others have. I can get the tokens etc but cannot figure out how to put it all together to play a stream. Is anyone else actively looking at this or has it gone cold?

I look at it when I have a chance. Last time I did was 12 days ago. I'd say any help in the area would be appreciated. It should be possible. We should have everything we need to start the stream. I wonder whether python-librtmp doesn't support all the features we need or we haven't hit the right arguments yet.

I pulled the private key and certs from the apk. Hopefully someone smarter than I can use them to get the stream to play?
certs.zip

@chaddotson @jwillaz did you see the certs the @njschwartz pulled from the APK?

↪ openssl  x509 -in wowza.netgear.com.crt  -subject -noout -dates
subject=C = US, ST = California, L = San Jose, O = "Netgear, Inc.", OU = IT, CN = wowza.netgear.com
notBefore=Aug 28 20:31:35 2014 GMT
notAfter=Aug 23 20:31:35 2034 GMT

↪ openssl  x509 -in client.crt   -subject -noout -dates
subject=C = US, ST = California, L = San Jose, O = Netgear Inc, OU = arlo, CN = fw, emailAddress = arlofw@netgear.com
notBefore=Jan  6 00:48:47 2017 GMT
notAfter=Jan  5 00:48:47 2021 GMT

↪ openssl x509 -in client.crt -pubkey -noout | openssl  md5
(stdin)= e32804cdc0c3d9d630e1fac594aa6002
↪ openssl  pkey  -in client-key.pem  -pubout  | openssl  md5
(stdin)= e32804cdc0c3d9d630e1fac594aa6002

Having the certs is definitely a good start. Unfortunately, I'm not sure how to use them. I don't have any experience with this protocol, and I've fallen into the same rut other have succumbed to with trying to playback the stream in something like FlowPlayer. If I could get my phone to properly proxy through Fiddler, I'd be interested in seeing the traffic from the Arlo app and also from the SmartThings integration to see if there are common calls.

Wondering if this Node solution actually works? See startStream.

https://github.com/zakmckracken1988/node-arlo-api/blob/master/arlo-api/index.js

@ryanwinter Been rereading the thread. Going back to your statement about the camera initiating the stream. I believe this indeed is the case, at least to netgear servers. It seems to me that the camera's poll every few seconds looking for incoming commands.

@chaddotson, this just means that all communications needs to be initiated through Netgears servers. Not really a problem as such, but kind of annoying cause it would be speedier to connect directly through to the camera.

I think the camera maintains a open connection to the server, maybe it polls instead.

@ryanwinter agreed no real issue there.

I've not had a chance to look into that node project I found.

It seems simply requesting the URL gets the camera to connect to netgear. Next thing that seems a bit wonky is that the netgear site doesn't get an updated thumbnail unless some video was transferred. Have we fully investigated the post payload?

Sorry to revive an old thread, but has there been any progress on this? I just got one of the 3-camera systems and I'm really bummed I can't integrate it into my normal HA system.

I've been too busy to look into it since my last post. I would still love to be able to script access.

@deanmcguire You got it! I've also recently figured out how to get up to date snapshots. I need to write it up and PR it though.

Anyone looking for snapshots, just issued the PR #65

Confirmed working with this package @deanmcguire . Setting user-agent to

'Mozilla/5.0 (iPhone; CPU iPhone OS 11_1_2 like Mac OS X) AppleWebKit/604.3.5 (KHTML, like Gecko) Mobile/15B202 NETGEAR/v1 (iOS Vuezone)'

With this, the camera live_streaming call yields a rtsp link. As he suggests in the other project, this must be changed to the secure rtsps. Once done, ffmpeg will process. I will start a PR for this.

@tchellomello could the fix @deanmcguire link to be applied to the HA-component?

Ok. successfully captured frames from the live stream using opencv (assuming the alternative user-agent is set). Thoughts about an optimal user-agent setting?

how do you change the user agent to iPhone, as mentioned above?

Got that working, now how do you keep the stream alive for more than 30 seconds?

@chaddotson any success?

Just jumping into this. I am using this example. I have 3 cameras I can print object with vars about the camera var is set cameras = arlo.GetDevices('camera'),print(cameras[1]). trying to get snapshot from the live stream running into this error when running the example EventStream' object has no attribute 'event_stream_thread. Any ideas?

Any other projects you guys know of that can guide us closer towards the goal?