Limit exposed go2rtc api to bare minimum (#8762)

* only permit GET requests to go2rtc

* bare minimum go2rtc passthrough

* support frigate card

* expose go2rtc streams data only
This commit is contained in:
Blake Blackshear 2023-11-28 00:25:47 +00:00 committed by GitHub
parent 15644a2b0c
commit a490c375f4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 56 additions and 20 deletions

View File

@ -164,19 +164,38 @@ http {
include proxy.conf;
}
location /live/mse/ {
proxy_pass http://go2rtc/;
# frigate lovelace card uses this path
location /live/mse/api/ws {
limit_except GET {
deny all;
}
proxy_pass http://go2rtc/api/ws;
include proxy.conf;
}
location /live/webrtc/ {
proxy_pass http://go2rtc/;
location /live/webrtc/api/ws {
limit_except GET {
deny all;
}
proxy_pass http://go2rtc/api/ws;
include proxy.conf;
}
location ~* /api/go2rtc([/]?.*)$ {
proxy_pass http://go2rtc;
rewrite ^/api/go2rtc(.*)$ /api$1 break;
# pass through go2rtc player
location /live/webrtc/webrtc.html {
limit_except GET {
deny all;
}
proxy_pass http://go2rtc/webrtc.html;
include proxy.conf;
}
# frontend uses this to fetch the version
location /api/go2rtc/api {
limit_except GET {
deny all;
}
proxy_pass http://go2rtc/api;
include proxy.conf;
}

View File

@ -16,6 +16,7 @@ from urllib.parse import unquote
import cv2
import numpy as np
import pytz
import requests
from flask import (
Blueprint,
Flask,
@ -1345,6 +1346,22 @@ def config_schema():
)
@bp.route("/go2rtc/streams")
def go2rtc_streams():
r = requests.get("http://127.0.0.1:1984/api/streams")
if not r.ok:
logger.error("Failed to fetch streams from go2rtc")
return make_response(
jsonify({"success": False, "message": "Error fetching stream data"}),
500,
)
stream_data = r.json()
for data in stream_data.values():
for producer in data["producers"]:
producer["url"] = clean_camera_user_pass(producer["url"])
return jsonify(stream_data)
@bp.route("/version")
def version():
return VERSION

View File

@ -41,7 +41,7 @@ export default function System() {
const cameraNames = Object.keys(cameras || emptyObject);
const processesNames = Object.keys(processes || emptyObject);
const { data: go2rtc } = useSWR('go2rtc');
const { data: go2rtc } = useSWR('go2rtc/api');
const onHandleFfprobe = async (camera, e) => {
if (e) {
@ -103,9 +103,9 @@ export default function System() {
className="text-blue-500 hover:underline"
target="_blank"
rel="noopener noreferrer"
href="/live/webrtc/"
href="/api/go2rtc/streams"
>
dashboard
streams info
</Link>
</span>
)}
@ -302,16 +302,16 @@ export default function System() {
<Tr>
<Th>GPU %</Th>
<Th>Memory %</Th>
{'dec' in gpu_usages[gpu] && (<Th>Decoder %</Th>)}
{'enc' in gpu_usages[gpu] && (<Th>Encoder %</Th>)}
{'dec' in gpu_usages[gpu] && <Th>Decoder %</Th>}
{'enc' in gpu_usages[gpu] && <Th>Encoder %</Th>}
</Tr>
</Thead>
<Tbody>
<Tr>
<Td>{gpu_usages[gpu]['gpu']}</Td>
<Td>{gpu_usages[gpu]['mem']}</Td>
{'dec' in gpu_usages[gpu] && (<Td>{gpu_usages[gpu]['dec']}</Td>)}
{'enc' in gpu_usages[gpu] && (<Td>{gpu_usages[gpu]['enc']}</Td>)}
{'dec' in gpu_usages[gpu] && <Td>{gpu_usages[gpu]['dec']}</Td>}
{'enc' in gpu_usages[gpu] && <Td>{gpu_usages[gpu]['enc']}</Td>}
</Tr>
</Tbody>
</Table>
@ -350,14 +350,14 @@ export default function System() {
<Link href={`/cameras/${camera}`}>{camera.replaceAll('_', ' ')}</Link>
<div className="flex">
{config.cameras[camera]['webui_url'] && (
<Button
href={config.cameras[camera]['webui_url']}
target="_blank"
>
Web UI<WebUI className="ml-1 h-4 w-4" fill="white" stroke="white" />
<Button href={config.cameras[camera]['webui_url']} target="_blank">
Web UI
<WebUI className="ml-1 h-4 w-4" fill="white" stroke="white" />
</Button>
)}
<Button className="ml-2" onClick={(e) => onHandleFfprobe(camera, e)}>ffprobe</Button>
<Button className="ml-2" onClick={(e) => onHandleFfprobe(camera, e)}>
ffprobe
</Button>
</div>
</div>
<div className="p-2">