QuantumEntangledAndy / neolink

An RTSP bridge to Reolink IP cameras
GNU Affero General Public License v3.0
330 stars 45 forks source link

Argus PT: TCP discovery fails #192

Closed iam-TJ closed 5 months ago

iam-TJ commented 10 months ago

I'm not sure if this is a bug, some misconfiguration, and whether in neolink or the Argus PT camera, but so far I've been unable to figure it out.

Due to issue #190 affecting my laptop I am now attempting connections from my workstation. In doing so I switched the config to "TCP discovery" and found that both workstation and laptop report a failure to connect even though network sniffing shows the camera's TCP RST packet being received.

So, on the workstation instead of broadcast discovery I configured neolink to use the camera's DHCP assigned IP address. Monitoring the network packets on the WiFi access point and on the workstation I see neolink issue a TCP SYN and the camera immediately replies with a RST (reset).

Using the laptop with "local discovery" (with uid = "..." set in the config) this is followed immediately with a UDP stream being sent by the camera to the laptop.

"TCP discovery" on the workstation reports:

 neolink/neolink_linux_x86_64_bookworm$ ./neolink rtsp --config=$HOME/.config/neolink/ArgusPT.toml
[2023-11-17T18:49:29Z INFO  neolink] Neolink 459c9255ada7ebda281eba32a8a9b94a30c471f0 release
[2023-11-17T18:49:29Z INFO  neolink::rtsp] Starting RTSP Server at 0.0.0.0:8554
[2023-11-17T18:49:29Z INFO  neolink::rtsp] argusPT: Rtsp Staring
[2023-11-17T18:49:29Z INFO  neolink::utils] argusPT: Connecting to camera at Address: 10.254.1.64
[2023-11-17T18:49:29Z INFO  neolink_core::bc_protocol] argusPT: Trying TCP discovery
[2023-11-17T18:49:29Z INFO  neolink_core::bc_protocol] argusPT: Discovery failed
[2023-11-17T18:49:29Z WARN  neolink::common::camthread] argusPT: Connection Lost: Failed to connect to camera argusPT at Address: 10.254.1.64 on channel 0

Caused by:
Cannot contact camera at given address
[2023-11-17T18:49:29Z INFO  neolink::common::camthread] argusPT: Attempt reconnect in 50ms

Yet as I reported network sniffing shows the workstation receives the TCP RST from the camera.

I then tested this same configuration ("TCP discovery") from the laptop and the same failure occurs even though the network sniffer shows the camera's TCP RST is received!

Config for both for "TCP discovery" is:

$ cat ~/.config/neolink/ArgusPT.toml
bind = "0.0.0.0"

[[cameras]]
name = "argusPT"
discovery = "local"
username = "admin"
#password = "password"
#uid = "95270004T22YP1W5"
address = "10.254.1.64"

When enabling the commented #uid on the laptop "Local discovery" succeeds. The workstation is on a different subnet so broadcast won't work for it, which is why I expected to use "TCP discovery" !

Here are screenshots of the network sniffing. 10.254.1.66/24 is the laptop; 10.254.`1.130/25 is the workstation. Termshark captures shown here are done on the access point. Screenshot_Termshark_laptop Screenshot_Termshark_workstation

iam-TJ commented 10 months ago

A follow-up after reading the source code. I cannot see how TCP Discovery is going to work when check_tcp() sends a dummy login (which presumably is expected to fail authentication but result in the camera sending a reply packet to prove it exists) but there is no subsequent valid authentication using the configured password - or in the case of the Argus PT and others like it, presumably no password at all.

iam-TJ commented 10 months ago

Digging further after building and installing the dissector I realised that the camera is simply refusing the TCP discovery to port 9000 completely - the connection attempt never progresses to talk the Baichuan protocol. This may infer that TCP discovery (IP address discovery) does not work for Argus PT.

iam-TJ commented 10 months ago

After a factory reset I did a packet capture of the Android Reolink application during an "Add Camera" workflow using QR-codes and with the IPv4 unable to escape the LAN to contact Internet servers. This appears to reveal that the Argus PT does not respond to UDP port 2000 probes nor any TCP probes, but only UDP broadcasts.

It also seems to cause multiple client ID discovery probes with identical data but different CIDs and that the Argus PT responds (eventually) to each CID probe with a unique DID. I'm not sure if this is intended or a slight bug in how the Android app operates if it doesn't receive an immediate reply to the first discovery probes.

I'm attaching the pcap file captured using tshark -P -w argusPT_reolink_app_discovery.pcap -i ap_soggy -f "ether host 38:ab:41:37:76:d2 or net 10.254.1.0/24 or broadcast" showing this in case it helps in the future. argusPT_reolink_app_discovery.zip

10.254.1.64 is the Argus PT 10.254.1.83 is the Android device

iam-TJ commented 10 months ago

I forgot to mention that in the capture above the Android app fails to complete the connection set-up - currently I'm not sure why but I'm beginning to suspect these battery/Wifi devices may only function correctly when permitted to connect via a relay to the Reolink Internet servers - which isn't going to happen!

111ar10 commented 9 months ago

Hi @iam-TJ

I haven't been digging in great detail like you with the network captures, but I played today with my 2 cameras (Argus PT, Argus PT Ultra) and came to conclusion that they simply won't work if I block them from Internet.

I have an NVR and 2 POE cameras connected to it and a standalone wired Lumus. All of those devices are on separate subnet/VLAN which don't have access to anything but a docker container running an NTP (to have synced time on NVR and cameras). My Main VLAN has access to isolated VLAN (with Reolink devices) with no restrictions.

I have tried first adding these battery operated Reolinks to Reolink app, but I can't add them as it says no network connection. I have them assigned static IPs on router. If I explicitly enable those IPs to reach Internet they can be added to app. Then I remove those firewall rules on router (cutting them off Internet) and lose connection to them...

With Neolink it behaves similarly (first played with IP, but I think that did not work, so used UID).

My suspicion is Reolink wants to have those cameras reliant on cloud (their servers). Which is also why they don't publish firmwares to be downloaded (and modified/hacked if possible).

Did you have any luck with further investigation?

111ar10 commented 9 months ago

@iam-TJ

After opening firewall (all udp traffic) from my camera to server where neolink is running in docker container it seems to work :)

How safe is it? My server is in VLAN which has full access to Internet, while camera is in VLAN with no access to Internet. Now neolink can connect to cameras.

iam-TJ commented 9 months ago

Thanks for the testing - I agree that these battery operated seem to need Internet link to a reolink/neolink servier constantly. I find it kind of ironic since with battery, plus the solar charger, they are perfect for off-grid use - which is my aim.

My camera is (still) in bits on the bench for the last month because I've had other things to do, but my intention is to desolder the Flash-storage chip so I can read its content via my TL866 chip reader.

I'm also aiming to connect a serial port header to it and hopefully be able to interact with the boot-loader and kernel/userspace using it.

Once I've done that I'll re-assemble the camera. That could be fun since I had to 'break' the antenna connection in the top section in order to strip the camera down completely. I'll publish photos at some point plus the content and analysis of the OS. If it contains Linux and GNU tools as I expect I'll persue Reolink for the source-code.

chrismanivong commented 5 months ago

I'm also aiming to connect a serial port header to it and hopefully be able to interact with the boot-loader and kernel/userspace using it.

Did you have any success on this @iam-TJ ?

QuantumEntangledAndy commented 5 months ago

Sorry for the delay been off the grid for awhile with life. Just thought I'd post about the protocols questions earlier and how it works.

There are two connection methods tcp and udp. Tcp is exclusively on port 9000 and udp on port 2018 or 2015. The battery cameras are udp only.

Normal client ops of a Reolink client is as follows:

  1. try tcp to any know IPs of the device on port 9000
  2. send a local broadcast on 255.255.255.255 to 2018
    • wait for a reply then login on the replies ip
  3. send a ip look up request to Reolink servers of the uid
    • if successful send a login to the ip at 2018
  4. send a request for Reolink to relay the connection to the camera

One thing no official client does is use stored ip information to connect over udp. (Step 3 without the server request). All official clients either rely on broadcasts (which are often blocked across sinners) or use Reolink servers.

Neolink therefore has one additional connection mode not present in official clients. If you supply both a uid and an IP address it will attempt a direct login request to that ip on 2018 using the udp. Therefore for maximum local connection success:

[[cameras]]
address = "19.168.1.x"
uid = "AUID"
discovery = "local"

This allows it to perform steps 1 and 2 as well as a step 3 but without the server look up. Under this configuration I expect you could block the camera for connecting it Reolink.

Not sure about dumping the firmware, but Reolink, from what I've seen of my E1, provides firmware to the camera over its baiuchan protocol. As we know the message format and how to extract the payload. If we can get a wireshark dump of an update in progress we should be able to extract the firmware from that.

QuantumEntangledAndy commented 5 months ago

My camera tried to get me to update via the app today so I thought I'd record the api calls for it

The api call is as follows:

curl 'https://apis.reolink.com/v1.0/devices/roms/latests/?uid={CAM_UID}&build={CAM_FIRMWARE_VERSION}&method=manual&mode=full&language=en-us' -o -

Response was this

{
    "needupdate": 1,
    "board": "",
    "version": "v3.0.0.115_20102200",
    "changelog": "",
    "files": [
        {
            "type": "full",
            "url": "https://firmwares.cdn.reolink.com/firmwares/IPC_517SD5.115_20102200.E1.GC4623.3MP.WIFI8188FTV.PT.REOLINK.pak",
            "name": "IPC_517SD5.115_20102200.E1.GC4623.3MP.WIFI8188FTV.PT.REOLINK.pak",
            "crc": 1746468470,
            "size": 9491791,
            "ver": "v3.0.0.115_20102200"
        }
    ]
}

Might be able to use this to grab the firmware for the battery cameras

chrismanivong commented 5 months ago

Great news, I disabled auto-updating yesterday already, to be able to grab some traffic. I also thought about firmware scraping, but as you already have a method, I'll wait on your message on success or not.

I checked to receive the firmware package from that URL, but it looks like the device needs to authenticate somehow. So we need to grab it for e.g. by sniffing it.

Once we have the firmware image somehow, I can assist in decomposing the firmware and do a deep analysis on device behaviour. Just let me know, I would really like to help here.

QuantumEntangledAndy commented 5 months ago

On the url it works fine for my E1 without authentication. But the Argus2E reports back with no update needed perhaps because I'm on latest already there.

QuantumEntangledAndy commented 5 months ago

I don't have any packet capture setup for my Argus 2E. So I won't be scraping for firmware myself, too many other things to do. But if anyone else has a packet dump of the firmware update I can check if it's in the baiuchan format and dump it form there

iam-TJ commented 5 months ago

I'm also aiming to connect a serial port header to it and hopefully be able to interact with the boot-loader and kernel/userspace using it.

Did you have any success on this @iam-TJ ?

Ha! The camera is still in bits on my workbench next to me. I had been planning to remove the Flash storage and read it but never had the time over winter. I'm not sure I will even be able to recall how to put it back together!

chrismanivong commented 5 months ago

@QuantumEntangledAndy this URL?

https://firmwares.cdn.reolink.com/firmwares/IPC_517SD5.115_20102200.E1.GC462 3.3MP.WIFI8188FTV.PT.REOLINK.pak

QuantumEntangledAndy commented 5 months ago

Yes

curl -LJO 'https://firmwares.cdn.reolink.com/firmwares/IPC_517SD5.115_20102200.E1.GC4623.3MP.WIFI8188FTV.PT.REOLINK.pak'

seems to work fine from my macos

QuantumEntangledAndy commented 5 months ago

Going to close this as its not really an actionble issue for me to address. But feel free to discus any connection setup or firmware stuff if you like and I'll see if I can respond