AlexxIT / go2rtc

Ultimate camera streaming application with support RTSP, RTMP, HTTP-FLV, WebRTC, MSE, HLS, MP4, MJPEG, HomeKit, FFmpeg, etc.
https://github.com/AlexxIT/Blog
MIT License
4.75k stars 382 forks source link

Feature request - Allow API listeners to take a list of IP addresses #966

Open Daniel-dev22 opened 7 months ago

Daniel-dev22 commented 7 months ago

I run frigate in a docker container that is attached to both an IPvlan and a bridge network. The bridge network IP is 192.168.10.12

However the way docker works with IPvlans is that even if you don't put ports in your docker compose, if the service (container) binds to a port on all IP addresses * or 0.0.0.0 it will be exposed on the ipvlan ip addresses as well. The only way to fix that is to only allow the service to bind to specific IP addresses rather than all.

Frigate does the same thing so I had to modify the nginx file to listen on the bridge network IP 192.168.10.12:5000 and 127.0.0.1:5000 but go2rtc doesn't let me do the same which means I'm exposing 1984 to my isolated camera IPvlan.

Frigate nginx

server {
     listen 127.0.0.1:5000;
     listen 192.168.10.12:5000;

What I'm looking for is to do this with go2rtc

api:
  listen:
  - 192.168.10.12:1984
  - 127.0.0.1:1984
  origin: '*'
AlexxIT commented 7 months ago

I don't see the point of not using 0.0.0.0. It's just a cosmetic tweak

Daniel-dev22 commented 7 months ago

I don't see the point of not using 0.0.0.0. It's just a cosmetic tweak

If I use that it binds to all IP addresses the container has available. I want it to bind to specific IP addresses not all.

By binding to specific IP addresses I can stop it from listening on my IPvlan address and only listen on the addresses I want it to listen on.

As mentioned in docker when using an ipvlan ports has no impact on whether the port is exposed for the ipvlan address. If a service binds to a port on that ipvlan address then it's exposed. The only way to stop this is to prevent the service from binding to that address in the first place.

I had to do this with home assistant as well using the server_host parameter

http:
  server_host: 
    - 192.168.10.4
skrashevich commented 7 months ago

What I'm looking for is to do this with go2rtc

api:
  listen:
  - 192.168.10.12:1984
  - 127.0.0.1:1984
  origin: '*'

the solution is unix sockets:

api:
  listen: 192.168.10.12:1984
  unix_listen: "/tmp/go2rtc.sock"  # default "", unix socket listener for API

and in frigate's nginx config

upstream go2rtc {
         server unix:/tmp/go2rtc.sock;
}

(look into my PR https://github.com/blakeblackshear/frigate/pull/8693)

Daniel-dev22 commented 7 months ago

What I'm looking for is to do this with go2rtc

api:
  listen:
  - 192.168.10.12:1984
  - 127.0.0.1:1984
  origin: '*'

the solution is unix sockets:

api:
  listen: 192.168.10.12:1984
  unix_listen: "/tmp/go2rtc.sock"  # default "", unix socket listener for API

and in frigate's nginx config

upstream go2rtc {
         server unix:/tmp/go2rtc.sock;
}

(look into my PR https://github.com/blakeblackshear/frigate/pull/8693)

Is a unix socket faster than tcp/ip connections and would this be local to the container or is this the unix socket on the localhost that the containers would connect to?

skrashevich commented 7 months ago

Theoretically, the sockets should be a little more faster than tcp/ip, but these are tenths of a percents. So, don’t worry about it :)

Look to a unix-socket as a virtual file in which one process writes data and the other immediately reads. That is, it will be local inside the container if you don't pull it out yourself

Daniel-dev22 commented 7 months ago

Theoretically, the sockets should be a little more faster than tcp/ip, but these are tenths of a percents. So, don’t worry about it :)

Look to a unix-socket as a virtual file in which one process writes data and the other immediately reads. That is, it will be local inside the container if you don't pull it out yourself

The unix-socket path worked thank you.

Daniel-dev22 commented 7 months ago

@skrashevich I think the health check also needs to be changed if go2rtc is not listening on 127.0.0.1 as it will cause false restarts https://github.com/blakeblackshear/frigate/blob/dev/docker/main/rootfs/etc/s6-overlay/s6-rc.d/go2rtc-healthcheck/run#L15

Daniel-dev22 commented 6 months ago

@AlexxIT

Unix sockets don't appear to be a good solution as they don't close connections fast enough at least not the current implementation by go2rtc doesn't.

The frigate v14 UI that can open a lot of connections at once when viewing the live page as it starts live streams automatically when an object is detected. Meaning a lot of cameras in view that suddenly have a lot of action can cause live streams to start, once the action stops the stream "closes". When the action occurs again the cycle continues. Then when switching to a specific camera view all previous connections are "closed". All of that combined results in a lot of opening and closing connections. However i suspect that the unix_sockets don't close immediately resulting in a lot of "closed" connections being left open for a period time and this is resulting in a significant performance impact as mse streams are freezing.

Is it possible to implement api listener taking a list of IP addresses so that can be used instead?