mirror of
https://github.com/blakeblackshear/frigate.git
synced 2024-11-21 19:07:46 +01:00
improve tls implementation (#11690)
* improve tls implementation * update docs
This commit is contained in:
parent
beefc51361
commit
e431031112
@ -35,6 +35,11 @@ ARG TARGETARCH
|
|||||||
WORKDIR /rootfs/usr/local/go2rtc/bin
|
WORKDIR /rootfs/usr/local/go2rtc/bin
|
||||||
ADD --link --chmod=755 "https://github.com/AlexxIT/go2rtc/releases/download/v1.9.2/go2rtc_linux_${TARGETARCH}" go2rtc
|
ADD --link --chmod=755 "https://github.com/AlexxIT/go2rtc/releases/download/v1.9.2/go2rtc_linux_${TARGETARCH}" go2rtc
|
||||||
|
|
||||||
|
FROM scratch AS tempio
|
||||||
|
ARG TARGETARCH
|
||||||
|
WORKDIR /rootfs/usr/local/tempio/bin
|
||||||
|
ADD --link --chmod=755 "https://github.com/home-assistant/tempio/releases/download/2021.09.0/tempio_${TARGETARCH}" tempio
|
||||||
|
|
||||||
|
|
||||||
####
|
####
|
||||||
#
|
#
|
||||||
@ -131,6 +136,7 @@ RUN pip3 wheel --wheel-dir=/wheels -r /requirements-wheels.txt
|
|||||||
FROM scratch AS deps-rootfs
|
FROM scratch AS deps-rootfs
|
||||||
COPY --from=nginx /usr/local/nginx/ /usr/local/nginx/
|
COPY --from=nginx /usr/local/nginx/ /usr/local/nginx/
|
||||||
COPY --from=go2rtc /rootfs/ /
|
COPY --from=go2rtc /rootfs/ /
|
||||||
|
COPY --from=tempio /rootfs/ /
|
||||||
COPY --from=s6-overlay /rootfs/ /
|
COPY --from=s6-overlay /rootfs/ /
|
||||||
COPY --from=models /rootfs/ /
|
COPY --from=models /rootfs/ /
|
||||||
COPY docker/main/rootfs/ /
|
COPY docker/main/rootfs/ /
|
||||||
@ -148,7 +154,7 @@ ARG APT_KEY_DONT_WARN_ON_DANGEROUS_USAGE=DontWarn
|
|||||||
ENV NVIDIA_VISIBLE_DEVICES=all
|
ENV NVIDIA_VISIBLE_DEVICES=all
|
||||||
ENV NVIDIA_DRIVER_CAPABILITIES="compute,video,utility"
|
ENV NVIDIA_DRIVER_CAPABILITIES="compute,video,utility"
|
||||||
|
|
||||||
ENV PATH="/usr/lib/btbn-ffmpeg/bin:/usr/local/go2rtc/bin:/usr/local/nginx/sbin:${PATH}"
|
ENV PATH="/usr/lib/btbn-ffmpeg/bin:/usr/local/go2rtc/bin:/usr/local/tempio/bin:/usr/local/nginx/sbin:${PATH}"
|
||||||
|
|
||||||
# Install dependencies
|
# Install dependencies
|
||||||
RUN --mount=type=bind,source=docker/main/install_deps.sh,target=/deps/install_deps.sh \
|
RUN --mount=type=bind,source=docker/main/install_deps.sh,target=/deps/install_deps.sh \
|
||||||
|
@ -10,16 +10,21 @@ echo "[INFO] Starting certsync..."
|
|||||||
|
|
||||||
lefile="/etc/letsencrypt/live/frigate/fullchain.pem"
|
lefile="/etc/letsencrypt/live/frigate/fullchain.pem"
|
||||||
|
|
||||||
|
tls_enabled=`python3 /usr/local/nginx/get_tls_settings.py | jq -r .enabled`
|
||||||
|
|
||||||
while true
|
while true
|
||||||
do
|
do
|
||||||
|
if [[ "$tls_enabled" == 'false' ]]; then
|
||||||
|
sleep 9999
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
|
||||||
if [ ! -e $lefile ]
|
if [ ! -e $lefile ]
|
||||||
then
|
then
|
||||||
echo "[ERROR] TLS certificate does not exist: $lefile"
|
echo "[ERROR] TLS certificate does not exist: $lefile"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
leprint=`openssl x509 -in $lefile -fingerprint -noout || echo 'failed'`
|
leprint=`openssl x509 -in $lefile -fingerprint -noout 2>&1 || echo 'failed'`
|
||||||
|
|
||||||
case "$leprint" in
|
case "$leprint" in
|
||||||
*Fingerprint*)
|
*Fingerprint*)
|
||||||
@ -29,7 +34,7 @@ do
|
|||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
|
|
||||||
liveprint=`echo | openssl s_client -showcerts -connect 127.0.0.1:443 2>&1 | openssl x509 -fingerprint | grep -i fingerprint || echo 'failed'`
|
liveprint=`echo | openssl s_client -showcerts -connect 127.0.0.1:8080 2>&1 | openssl x509 -fingerprint 2>&1 | grep -i fingerprint || echo 'failed'`
|
||||||
|
|
||||||
case "$liveprint" in
|
case "$liveprint" in
|
||||||
*Fingerprint*)
|
*Fingerprint*)
|
||||||
|
@ -33,9 +33,14 @@ if [ ! \( -f "$letsencrypt_path/privkey.pem" -a -f "$letsencrypt_path/fullchain.
|
|||||||
echo "[INFO] No TLS certificate found. Generating a self signed certificate..."
|
echo "[INFO] No TLS certificate found. Generating a self signed certificate..."
|
||||||
openssl req -new -newkey rsa:4096 -days 365 -nodes -x509 \
|
openssl req -new -newkey rsa:4096 -days 365 -nodes -x509 \
|
||||||
-subj "/O=FRIGATE DEFAULT CERT/CN=*" \
|
-subj "/O=FRIGATE DEFAULT CERT/CN=*" \
|
||||||
-keyout "$letsencrypt_path/privkey.pem" -out "$letsencrypt_path/fullchain.pem"
|
-keyout "$letsencrypt_path/privkey.pem" -out "$letsencrypt_path/fullchain.pem" 2>/dev/null
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# build templates for optional TLS support
|
||||||
|
python3 /usr/local/nginx/get_tls_settings.py | \
|
||||||
|
tempio -template /usr/local/nginx/templates/listen.gotmpl \
|
||||||
|
-out /usr/local/nginx/conf/listen.conf
|
||||||
|
|
||||||
# Replace the bash process with the NGINX process, redirecting stderr to stdout
|
# Replace the bash process with the NGINX process, redirecting stderr to stdout
|
||||||
exec 2>&1
|
exec 2>&1
|
||||||
exec \
|
exec \
|
||||||
|
@ -59,20 +59,10 @@ http {
|
|||||||
include go2rtc_upstream.conf;
|
include go2rtc_upstream.conf;
|
||||||
|
|
||||||
server {
|
server {
|
||||||
listen [::]:80 ipv6only=off default_server;
|
|
||||||
|
|
||||||
location / {
|
|
||||||
return 301 https://$host$request_uri;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
server {
|
|
||||||
# intended for external traffic, protected by auth
|
|
||||||
listen [::]:8080 ipv6only=off;
|
|
||||||
# intended for internal traffic, not protected by auth
|
# intended for internal traffic, not protected by auth
|
||||||
listen [::]:5000 ipv6only=off;
|
listen [::]:5000 ipv6only=off;
|
||||||
|
|
||||||
include tls.conf;
|
include listen.conf;
|
||||||
|
|
||||||
# vod settings
|
# vod settings
|
||||||
vod_base_url '';
|
vod_base_url '';
|
||||||
|
28
docker/main/rootfs/usr/local/nginx/get_tls_settings.py
Normal file
28
docker/main/rootfs/usr/local/nginx/get_tls_settings.py
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
"""Prints the tls config as json to stdout."""
|
||||||
|
|
||||||
|
import json
|
||||||
|
import os
|
||||||
|
|
||||||
|
import yaml
|
||||||
|
|
||||||
|
config_file = os.environ.get("CONFIG_FILE", "/config/config.yml")
|
||||||
|
|
||||||
|
# Check if we can use .yaml instead of .yml
|
||||||
|
config_file_yaml = config_file.replace(".yml", ".yaml")
|
||||||
|
if os.path.isfile(config_file_yaml):
|
||||||
|
config_file = config_file_yaml
|
||||||
|
|
||||||
|
try:
|
||||||
|
with open(config_file) as f:
|
||||||
|
raw_config = f.read()
|
||||||
|
|
||||||
|
if config_file.endswith((".yaml", ".yml")):
|
||||||
|
config: dict[str, any] = yaml.safe_load(raw_config)
|
||||||
|
elif config_file.endswith(".json"):
|
||||||
|
config: dict[str, any] = json.loads(raw_config)
|
||||||
|
except FileNotFoundError:
|
||||||
|
config: dict[str, any] = {}
|
||||||
|
|
||||||
|
tls_config: dict[str, any] = config.get("tls", {})
|
||||||
|
|
||||||
|
print(json.dumps(tls_config))
|
@ -1,5 +1,9 @@
|
|||||||
keepalive_timeout 70;
|
{{ if not .enabled }}
|
||||||
listen [::]:443 ipv6only=off default_server ssl;
|
# intended for external traffic, protected by auth
|
||||||
|
listen [::]:8080 ipv6only=off;
|
||||||
|
{{ else }}
|
||||||
|
# intended for external traffic, protected by auth
|
||||||
|
listen [::]:8080 ipv6only=off ssl;
|
||||||
|
|
||||||
ssl_certificate /etc/letsencrypt/live/frigate/fullchain.pem;
|
ssl_certificate /etc/letsencrypt/live/frigate/fullchain.pem;
|
||||||
ssl_certificate_key /etc/letsencrypt/live/frigate/privkey.pem;
|
ssl_certificate_key /etc/letsencrypt/live/frigate/privkey.pem;
|
||||||
@ -22,3 +26,5 @@ location /.well-known/acme-challenge/ {
|
|||||||
default_type "text/plain";
|
default_type "text/plain";
|
||||||
root /etc/letsencrypt/www;
|
root /etc/letsencrypt/www;
|
||||||
}
|
}
|
||||||
|
{{ end }}
|
||||||
|
|
@ -63,6 +63,11 @@ database:
|
|||||||
# The path to store the SQLite DB (default: shown below)
|
# The path to store the SQLite DB (default: shown below)
|
||||||
path: /config/frigate.db
|
path: /config/frigate.db
|
||||||
|
|
||||||
|
# Optional: TLS configuration
|
||||||
|
tls:
|
||||||
|
# Optional: Enable TLS for port 8080 (default: shown below)
|
||||||
|
enabled: true
|
||||||
|
|
||||||
# Optional: Authentication configuration
|
# Optional: Authentication configuration
|
||||||
auth:
|
auth:
|
||||||
# Optional: Authentication mode (default: shown below)
|
# Optional: Authentication mode (default: shown below)
|
||||||
|
@ -11,7 +11,7 @@ Frigate uses [go2rtc](https://github.com/AlexxIT/go2rtc/tree/v1.9.2) to provide
|
|||||||
|
|
||||||
:::note
|
:::note
|
||||||
|
|
||||||
You can access the go2rtc stream info at `http://frigate_ip:8080/api/go2rtc/streams` which can be helpful to debug as well as provide useful information about your camera streams.
|
You can access the go2rtc stream info at `/api/go2rtc/streams` which can be helpful to debug as well as provide useful information about your camera streams.
|
||||||
|
|
||||||
:::
|
:::
|
||||||
|
|
||||||
|
@ -5,9 +5,9 @@ title: TLS
|
|||||||
|
|
||||||
# TLS
|
# TLS
|
||||||
|
|
||||||
Frigate's integrated NGINX server supports TLS certificates. By default Frigate will generate a self signed certificate that will be used for port 443. Frigate is designed to make it easy to use whatever tool you prefer to manage certificates.
|
Frigate's integrated NGINX server supports TLS certificates. By default Frigate will generate a self signed certificate that will be used for port 8080. Frigate is designed to make it easy to use whatever tool you prefer to manage certificates.
|
||||||
|
|
||||||
Frigate is often running behind a reverse proxy that manages TLS certificates for multiple services. However, if you are running on a device that's separate from your proxy or if you expose Frigate directly to the internet, you may want to configure TLS.
|
Frigate is often running behind a reverse proxy that manages TLS certificates for multiple services. You will likely need to set your reverse proxy to allow self signed certificates or you can disable TLS in Frigate's config. However, if you are running on a dedicated device that's separate from your proxy or if you expose Frigate directly to the internet, you may want to configure TLS with valid certificates.
|
||||||
|
|
||||||
## Certificates
|
## Certificates
|
||||||
|
|
||||||
@ -25,10 +25,16 @@ Within the folder, the private key is expected to be named `privkey.pem` and the
|
|||||||
|
|
||||||
Frigate automatically compares the fingerprint of the certificate at `/etc/letsencrypt/live/frigate/fullchain.pem` against the fingerprint of the TLS cert in NGINX every minute. If these differ, the NGINX config is reloaded to pick up the updated certificate.
|
Frigate automatically compares the fingerprint of the certificate at `/etc/letsencrypt/live/frigate/fullchain.pem` against the fingerprint of the TLS cert in NGINX every minute. If these differ, the NGINX config is reloaded to pick up the updated certificate.
|
||||||
|
|
||||||
|
If you issue Frigate valid certificates you will likely want to configure it to run on port 443 so you can access it without a port number like `https://your-frigate-domain.com` by mapping 8080 to 443.
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
frigate:
|
||||||
|
...
|
||||||
|
ports:
|
||||||
|
- "443:8080"
|
||||||
|
...
|
||||||
|
```
|
||||||
|
|
||||||
## ACME Challenge
|
## ACME Challenge
|
||||||
|
|
||||||
Frigate also supports hosting the acme challenge files for the HTTP challenge method if needed. The challenge files should be mounted at `/etc/letsencrypt/www`.
|
Frigate also supports hosting the acme challenge files for the HTTP challenge method if needed. The challenge files should be mounted at `/etc/letsencrypt/www`.
|
||||||
|
|
||||||
## Advanced customization
|
|
||||||
|
|
||||||
If you would like to customize the TLS configuration, you can do so by using a bind mount to override `/usr/local/nginx/conf/tls.conf`. Check the source code for the default configuration and modify from there.
|
|
||||||
|
@ -35,7 +35,6 @@ The following ports are used by Frigate and can be mapped via docker as required
|
|||||||
| Port | Description |
|
| Port | Description |
|
||||||
| ------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
| ------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||||
| `8080` | Authenticated UI and API access without TLS. Reverse proxies should use this port. |
|
| `8080` | Authenticated UI and API access without TLS. Reverse proxies should use this port. |
|
||||||
| `443` | Authenticated UI and API access with TLS. See the [TLS configuration](/configuration/tls) for more details. |
|
|
||||||
| `5000` | Internal unauthenticated UI and API access. Access to this port should be limited. Intended to be used within the docker network for services that integrate with Frigate. |
|
| `5000` | Internal unauthenticated UI and API access. Access to this port should be limited. Intended to be used within the docker network for services that integrate with Frigate. |
|
||||||
| `8554` | RTSP restreaming. By default, these streams are unauthenticated. Authentication can be configured in go2rtc section of config. |
|
| `8554` | RTSP restreaming. By default, these streams are unauthenticated. Authentication can be configured in go2rtc section of config. |
|
||||||
| `8555` | WebRTC connections for low latency live views. |
|
| `8555` | WebRTC connections for low latency live views. |
|
||||||
|
@ -137,7 +137,7 @@ cameras:
|
|||||||
- detect
|
- detect
|
||||||
```
|
```
|
||||||
|
|
||||||
Now you should be able to start Frigate by running `docker compose up -d` from within the folder containing `docker-compose.yml`. On startup, an admin user and password will be created and outputted in the logs. You can see this by running `docker logs frigate`. Frigate should now be accessible at `server_ip:8080` where you can login with the `admin` user and finish the configuration using the built-in configuration editor.
|
Now you should be able to start Frigate by running `docker compose up -d` from within the folder containing `docker-compose.yml`. On startup, an admin user and password will be created and outputted in the logs. You can see this by running `docker logs frigate`. Frigate should now be accessible at `https://server_ip:8080` where you can login with the `admin` user and finish the configuration using the built-in configuration editor.
|
||||||
|
|
||||||
## Configuring Frigate
|
## Configuring Frigate
|
||||||
|
|
||||||
|
@ -164,7 +164,7 @@ Accepts the following query string parameters:
|
|||||||
| `motion` | int | Draw blue boxes for areas with detected motion (0 or 1) |
|
| `motion` | int | Draw blue boxes for areas with detected motion (0 or 1) |
|
||||||
| `regions` | int | Draw green boxes for areas where object detection was run (0 or 1) |
|
| `regions` | int | Draw green boxes for areas where object detection was run (0 or 1) |
|
||||||
|
|
||||||
You can access a higher resolution mjpeg stream by appending `h=height-in-pixels` to the endpoint. For example `http://localhost:8080/api/back?h=1080`. You can also increase the FPS by appending `fps=frame-rate` to the URL such as `http://localhost:8080/api/back?fps=10` or both with `?fps=10&h=1000`.
|
You can access a higher resolution mjpeg stream by appending `h=height-in-pixels` to the endpoint. For example `/api/back?h=1080`. You can also increase the FPS by appending `fps=frame-rate` to the URL such as `/api/back?fps=10` or both with `?fps=10&h=1000`.
|
||||||
|
|
||||||
### `GET /api/<camera_name>/latest.jpg[?h=300]`
|
### `GET /api/<camera_name>/latest.jpg[?h=300]`
|
||||||
|
|
||||||
@ -496,21 +496,21 @@ Delete review items.
|
|||||||
|
|
||||||
Get the motion activity for camera(s) during a specified time period.
|
Get the motion activity for camera(s) during a specified time period.
|
||||||
|
|
||||||
| param | Type | Description |
|
| param | Type | Description |
|
||||||
| ---------- | ---- | -------------------------------------------------------------- |
|
| --------- | ---- | --------------------------- |
|
||||||
| `before` | int | Epoch time |
|
| `before` | int | Epoch time |
|
||||||
| `after` | int | Epoch time |
|
| `after` | int | Epoch time |
|
||||||
| `cameras` | str | , separated list of cameras |
|
| `cameras` | str | , separated list of cameras |
|
||||||
|
|
||||||
### `GET /review/activity/audio`
|
### `GET /review/activity/audio`
|
||||||
|
|
||||||
Get the audio activity for camera(s) during a specified time period.
|
Get the audio activity for camera(s) during a specified time period.
|
||||||
|
|
||||||
| param | Type | Description |
|
| param | Type | Description |
|
||||||
| ---------- | ---- | -------------------------------------------------------------- |
|
| --------- | ---- | --------------------------- |
|
||||||
| `before` | int | Epoch time |
|
| `before` | int | Epoch time |
|
||||||
| `after` | int | Epoch time |
|
| `after` | int | Epoch time |
|
||||||
| `cameras` | str | , separated list of cameras |
|
| `cameras` | str | , separated list of cameras |
|
||||||
|
|
||||||
## Timeline
|
## Timeline
|
||||||
|
|
||||||
|
@ -115,6 +115,10 @@ class UIConfig(FrigateBaseModel):
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class TlsConfig(FrigateBaseModel):
|
||||||
|
enabled: bool = Field(default=True, title="Enable TLS for port 8080")
|
||||||
|
|
||||||
|
|
||||||
class AuthModeEnum(str, Enum):
|
class AuthModeEnum(str, Enum):
|
||||||
native = "native"
|
native = "native"
|
||||||
proxy = "proxy"
|
proxy = "proxy"
|
||||||
@ -1303,6 +1307,7 @@ class FrigateConfig(FrigateBaseModel):
|
|||||||
database: DatabaseConfig = Field(
|
database: DatabaseConfig = Field(
|
||||||
default_factory=DatabaseConfig, title="Database configuration."
|
default_factory=DatabaseConfig, title="Database configuration."
|
||||||
)
|
)
|
||||||
|
tls: TlsConfig = Field(default_factory=TlsConfig, title="TLS configuration.")
|
||||||
auth: AuthConfig = Field(default_factory=AuthConfig, title="Auth configuration.")
|
auth: AuthConfig = Field(default_factory=AuthConfig, title="Auth configuration.")
|
||||||
environment_vars: Dict[str, str] = Field(
|
environment_vars: Dict[str, str] = Field(
|
||||||
default_factory=dict, title="Frigate environment variables."
|
default_factory=dict, title="Frigate environment variables."
|
||||||
|
Loading…
Reference in New Issue
Block a user