mirror of
https://github.com/blakeblackshear/frigate.git
synced 2025-09-26 19:41:29 +08:00
TLS support (#11678)
* implement self signed cert and monitor/reload * move go2rtc upstream to separate file * add directory for ACME challenges * make certsync more resilient * add TLS docs * add jwt secret info to docs
This commit is contained in:
@@ -0,0 +1 @@
|
||||
certsync
|
@@ -0,0 +1 @@
|
||||
certsync-pipeline
|
4
docker/main/rootfs/etc/s6-overlay/s6-rc.d/certsync-log/run
Executable file
4
docker/main/rootfs/etc/s6-overlay/s6-rc.d/certsync-log/run
Executable file
@@ -0,0 +1,4 @@
|
||||
#!/command/with-contenv bash
|
||||
# shellcheck shell=bash
|
||||
|
||||
exec logutil-service /dev/shm/logs/certsync
|
@@ -0,0 +1 @@
|
||||
longrun
|
30
docker/main/rootfs/etc/s6-overlay/s6-rc.d/certsync/finish
Executable file
30
docker/main/rootfs/etc/s6-overlay/s6-rc.d/certsync/finish
Executable file
@@ -0,0 +1,30 @@
|
||||
#!/command/with-contenv bash
|
||||
# shellcheck shell=bash
|
||||
# Take down the S6 supervision tree when the service fails
|
||||
|
||||
set -o errexit -o nounset -o pipefail
|
||||
|
||||
# Logs should be sent to stdout so that s6 can collect them
|
||||
|
||||
declare exit_code_container
|
||||
exit_code_container=$(cat /run/s6-linux-init-container-results/exitcode)
|
||||
readonly exit_code_container
|
||||
readonly exit_code_service="${1}"
|
||||
readonly exit_code_signal="${2}"
|
||||
readonly service="CERTSYNC"
|
||||
|
||||
echo "[INFO] Service ${service} exited with code ${exit_code_service} (by signal ${exit_code_signal})"
|
||||
|
||||
if [[ "${exit_code_service}" -eq 256 ]]; then
|
||||
if [[ "${exit_code_container}" -eq 0 ]]; then
|
||||
echo $((128 + exit_code_signal)) >/run/s6-linux-init-container-results/exitcode
|
||||
fi
|
||||
if [[ "${exit_code_signal}" -eq 15 ]]; then
|
||||
exec /run/s6/basedir/bin/halt
|
||||
fi
|
||||
elif [[ "${exit_code_service}" -ne 0 ]]; then
|
||||
if [[ "${exit_code_container}" -eq 0 ]]; then
|
||||
echo "${exit_code_service}" >/run/s6-linux-init-container-results/exitcode
|
||||
fi
|
||||
exec /run/s6/basedir/bin/halt
|
||||
fi
|
@@ -0,0 +1 @@
|
||||
certsync-log
|
53
docker/main/rootfs/etc/s6-overlay/s6-rc.d/certsync/run
Executable file
53
docker/main/rootfs/etc/s6-overlay/s6-rc.d/certsync/run
Executable file
@@ -0,0 +1,53 @@
|
||||
#!/command/with-contenv bash
|
||||
# shellcheck shell=bash
|
||||
# Start the CERTSYNC service
|
||||
|
||||
set -o errexit -o nounset -o pipefail
|
||||
|
||||
# Logs should be sent to stdout so that s6 can collect them
|
||||
|
||||
echo "[INFO] Starting certsync..."
|
||||
|
||||
lefile="/etc/letsencrypt/live/frigate/fullchain.pem"
|
||||
|
||||
|
||||
while true
|
||||
do
|
||||
|
||||
if [ ! -e $lefile ]
|
||||
then
|
||||
echo "[ERROR] TLS certificate does not exist: $lefile"
|
||||
fi
|
||||
|
||||
leprint=`openssl x509 -in $lefile -fingerprint -noout || echo 'failed'`
|
||||
|
||||
case "$leprint" in
|
||||
*Fingerprint*)
|
||||
;;
|
||||
*)
|
||||
echo "[ERROR] Missing fingerprint from $lefile"
|
||||
;;
|
||||
esac
|
||||
|
||||
liveprint=`echo | openssl s_client -showcerts -connect 127.0.0.1:443 2>&1 | openssl x509 -fingerprint | grep -i fingerprint || echo 'failed'`
|
||||
|
||||
case "$liveprint" in
|
||||
*Fingerprint*)
|
||||
;;
|
||||
*)
|
||||
echo "[ERROR] Missing fingerprint from current nginx TLS cert"
|
||||
;;
|
||||
esac
|
||||
|
||||
if [[ "$leprint" != "failed" && "$liveprint" != "failed" && "$leprint" != "$liveprint" ]]
|
||||
then
|
||||
echo "[INFO] Reloading nginx to refresh TLS certificate"
|
||||
echo "$lefile: $leprint"
|
||||
/usr/local/nginx/sbin/nginx -s reload
|
||||
fi
|
||||
|
||||
sleep 60
|
||||
|
||||
done
|
||||
|
||||
exit 0
|
@@ -0,0 +1 @@
|
||||
30000
|
1
docker/main/rootfs/etc/s6-overlay/s6-rc.d/certsync/type
Normal file
1
docker/main/rootfs/etc/s6-overlay/s6-rc.d/certsync/type
Normal file
@@ -0,0 +1 @@
|
||||
longrun
|
@@ -4,7 +4,7 @@
|
||||
|
||||
set -o errexit -o nounset -o pipefail
|
||||
|
||||
dirs=(/dev/shm/logs/frigate /dev/shm/logs/go2rtc /dev/shm/logs/nginx)
|
||||
dirs=(/dev/shm/logs/frigate /dev/shm/logs/go2rtc /dev/shm/logs/nginx /dev/shm/logs/certsync)
|
||||
|
||||
mkdir -p "${dirs[@]}"
|
||||
chown nobody:nogroup "${dirs[@]}"
|
||||
|
5
docker/main/rootfs/etc/s6-overlay/s6-rc.d/nginx/data/check
Executable file
5
docker/main/rootfs/etc/s6-overlay/s6-rc.d/nginx/data/check
Executable file
@@ -0,0 +1,5 @@
|
||||
#!/usr/bin/env bash
|
||||
set -e
|
||||
|
||||
# Wait for PID file to exist.
|
||||
while ! test -f /run/nginx.pid; do sleep 1; done
|
@@ -0,0 +1 @@
|
||||
3
|
@@ -22,6 +22,22 @@ function set_worker_processes() {
|
||||
|
||||
set_worker_processes
|
||||
|
||||
# ensure the directory for ACME challenges exists
|
||||
mkdir -p /etc/letsencrypt/www
|
||||
|
||||
# Create self signed certs if needed
|
||||
letsencrypt_path=/etc/letsencrypt/live/frigate
|
||||
mkdir -p $letsencrypt_path
|
||||
|
||||
if [ ! \( -f "$letsencrypt_path/privkey.pem" -a -f "$letsencrypt_path/fullchain.pem" \) ]; then
|
||||
echo "[INFO] No TLS certificate found. Generating a self signed certificate..."
|
||||
openssl req -new -newkey rsa:4096 -days 365 -nodes -x509 \
|
||||
-subj "/O=FRIGATE DEFAULT CERT/CN=*" \
|
||||
-keyout "$letsencrypt_path/privkey.pem" -out "$letsencrypt_path/fullchain.pem"
|
||||
fi
|
||||
|
||||
# Replace the bash process with the NGINX process, redirecting stderr to stdout
|
||||
exec 2>&1
|
||||
exec nginx
|
||||
exec \
|
||||
s6-notifyoncheck -t 30000 -n 1 \
|
||||
nginx
|
||||
|
@@ -0,0 +1,4 @@
|
||||
upstream go2rtc {
|
||||
server 127.0.0.1:1984;
|
||||
keepalive 1024;
|
||||
}
|
@@ -56,9 +56,14 @@ http {
|
||||
keepalive 1024;
|
||||
}
|
||||
|
||||
upstream go2rtc {
|
||||
server 127.0.0.1:1984;
|
||||
keepalive 1024;
|
||||
include go2rtc_upstream.conf;
|
||||
|
||||
server {
|
||||
listen [::]:80 ipv6only=off default_server;
|
||||
|
||||
location / {
|
||||
return 301 https://$host$request_uri;
|
||||
}
|
||||
}
|
||||
|
||||
server {
|
||||
@@ -67,6 +72,8 @@ http {
|
||||
# intended for internal traffic, not protected by auth
|
||||
listen [::]:5000 ipv6only=off;
|
||||
|
||||
include tls.conf;
|
||||
|
||||
# vod settings
|
||||
vod_base_url '';
|
||||
vod_segments_base_url '';
|
||||
|
24
docker/main/rootfs/usr/local/nginx/conf/tls.conf
Normal file
24
docker/main/rootfs/usr/local/nginx/conf/tls.conf
Normal file
@@ -0,0 +1,24 @@
|
||||
keepalive_timeout 70;
|
||||
listen [::]:443 ipv6only=off default_server ssl;
|
||||
|
||||
ssl_certificate /etc/letsencrypt/live/frigate/fullchain.pem;
|
||||
ssl_certificate_key /etc/letsencrypt/live/frigate/privkey.pem;
|
||||
|
||||
# generated 2024-06-01, Mozilla Guideline v5.7, nginx 1.25.3, OpenSSL 1.1.1w, modern configuration, no OCSP
|
||||
# https://ssl-config.mozilla.org/#server=nginx&version=1.25.3&config=modern&openssl=1.1.1w&ocsp=false&guideline=5.7
|
||||
ssl_session_timeout 1d;
|
||||
ssl_session_cache shared:MozSSL:10m; # about 40000 sessions
|
||||
ssl_session_tickets off;
|
||||
|
||||
# modern configuration
|
||||
ssl_protocols TLSv1.3;
|
||||
ssl_prefer_server_ciphers off;
|
||||
|
||||
# HSTS (ngx_http_headers_module is required) (63072000 seconds)
|
||||
add_header Strict-Transport-Security "max-age=63072000" always;
|
||||
|
||||
# ACME challenge location
|
||||
location /.well-known/acme-challenge/ {
|
||||
default_type "text/plain";
|
||||
root /etc/letsencrypt/www;
|
||||
}
|
Reference in New Issue
Block a user