Serve the site over HTTPS with self signed certificates
This commit is contained in:
@@ -15,3 +15,4 @@ target
|
|||||||
data
|
data
|
||||||
PROJECT.md
|
PROJECT.md
|
||||||
UPDATE.md
|
UPDATE.md
|
||||||
|
infra/certs
|
||||||
|
|||||||
@@ -72,6 +72,9 @@ docker compose -f infra/docker-compose.yml up -d
|
|||||||
| API | 8080 |
|
| API | 8080 |
|
||||||
| LiveKit | 7880 |
|
| LiveKit | 7880 |
|
||||||
|
|
||||||
|
Anything other than localhost also wants HTTPS, or browsers will refuse the camera and screen
|
||||||
|
sharing. See below.
|
||||||
|
|
||||||
If the host runs a firewall, open the LiveKit ports:
|
If the host runs a firewall, open the LiveKit ports:
|
||||||
|
|
||||||
```
|
```
|
||||||
@@ -94,6 +97,61 @@ host. LiveKit reads that file literally, so it does not pick up environment vari
|
|||||||
Leaving `CORS_ORIGINS` on its localhost default while browsing by LAN address is the usual cause
|
Leaving `CORS_ORIGINS` on its localhost default while browsing by LAN address is the usual cause
|
||||||
of requests failing with a missing `Access-Control-Allow-Origin` header.
|
of requests failing with a missing `Access-Control-Allow-Origin` header.
|
||||||
|
|
||||||
|
### HTTPS
|
||||||
|
|
||||||
|
Browsers only hand out the camera or the screen on a secure origin. `localhost` counts as one, a
|
||||||
|
LAN address does not, so on `http://192.168.1.45:3000` sharing is refused before PiStation ever
|
||||||
|
sees the request. That needs a certificate:
|
||||||
|
|
||||||
|
```
|
||||||
|
./infra/certs.sh
|
||||||
|
docker compose -f infra/docker-compose.yml --profile tls up -d
|
||||||
|
```
|
||||||
|
|
||||||
|
The script reads the addresses out of `infra/.env`, creates a certificate authority of your own
|
||||||
|
and issues one certificate covering all of them, plus `localhost` and the machine's LAN address.
|
||||||
|
Pass `--host` for a name it cannot work out, like a router alias. An nginx container then
|
||||||
|
terminates TLS in front of all three services:
|
||||||
|
|
||||||
|
| Service | Plain | Encrypted |
|
||||||
|
| --- | --- | --- |
|
||||||
|
| Website | 3000 | 3443 |
|
||||||
|
| API | 8080 | 8443 |
|
||||||
|
| LiveKit | 7880 | 7443 |
|
||||||
|
|
||||||
|
Point `infra/.env` at the encrypted ports and recreate the stack. The script prints the exact
|
||||||
|
lines to paste:
|
||||||
|
|
||||||
|
```
|
||||||
|
PUBLIC_WEB_URL=https://192.168.1.45:3443
|
||||||
|
PUBLIC_API_URL=https://192.168.1.45:8443
|
||||||
|
PUBLIC_LIVEKIT_URL=wss://192.168.1.45:7443
|
||||||
|
CORS_ORIGINS=https://192.168.1.45:3443
|
||||||
|
```
|
||||||
|
|
||||||
|
All three move together. A page served over HTTPS cannot call a plain API or open a plain
|
||||||
|
websocket, and the browser blocks the attempt as mixed content.
|
||||||
|
|
||||||
|
Nobody will sign a certificate for an address they do not own, so this one is signed by an
|
||||||
|
authority that exists only on your machine and no device trusts it yet. Install
|
||||||
|
`infra/certs/ca.crt` once per device and the warnings stop:
|
||||||
|
|
||||||
|
| Device | Where |
|
||||||
|
| --- | --- |
|
||||||
|
| Android | Settings, Security, Encryption and credentials, Install a certificate |
|
||||||
|
| iOS | Mail it to yourself, open it, install the profile, then trust it under General, About, Certificate Trust Settings |
|
||||||
|
| macOS | Open it in Keychain Access, add to System, set it to Always Trust |
|
||||||
|
| Windows | Install into Trusted Root Certification Authorities for the local machine |
|
||||||
|
| Linux and kiosks | Copy to `/usr/local/share/ca-certificates/` and run `update-ca-certificates` |
|
||||||
|
|
||||||
|
Clicking through the browser warning instead mostly works, but it is three separate warnings,
|
||||||
|
since each port is its own origin, and it has to be redone on every device. Kiosks get no warning
|
||||||
|
to click through at all, so they need the authority installed.
|
||||||
|
|
||||||
|
Certificates last 825 days, the longest Safari accepts. Re-running the script issues a fresh one
|
||||||
|
and keeps the same authority, so devices stay trusted. `--new-ca` replaces the authority and
|
||||||
|
means installing it everywhere again.
|
||||||
|
|
||||||
The LiveKit container uses host networking, because WebRTC needs to advertise an address your
|
The LiveKit container uses host networking, because WebRTC needs to advertise an address your
|
||||||
devices can reach and a container on a bridge network has none. That is Linux only; on macOS or
|
devices can reach and a container on a bridge network has none. That is Linux only; on macOS or
|
||||||
Windows, run LiveKit outside Docker.
|
Windows, run LiveKit outside Docker.
|
||||||
@@ -128,8 +186,16 @@ Raspberry Pi OS ships with 100 MB of swap, which a 512 MB Zero 2 W exhausts as s
|
|||||||
browser engine and the media stack are both running. Without more, the kernel starts killing
|
browser engine and the media stack are both running. Without more, the kernel starts killing
|
||||||
processes and the kiosk appears to restart at random.
|
processes and the kiosk appears to restart at random.
|
||||||
|
|
||||||
Useful flags: `--server`, `--join-url`, `--package-url`, `--user`, `--profile`, `--swap`,
|
On a self signed server, copy `infra/certs/ca.crt` to the Pi first and point the installer at it,
|
||||||
`--skip-reboot`.
|
or nothing it downloads will verify:
|
||||||
|
|
||||||
|
```
|
||||||
|
scp infra/certs/ca.crt pi@your-kiosk:
|
||||||
|
curl -fsSL http://your-server:8080/install.sh | sudo bash -s -- --key <token> --ca-cert ./ca.crt
|
||||||
|
```
|
||||||
|
|
||||||
|
Useful flags: `--server`, `--join-url`, `--package-url`, `--user`, `--ca-cert`, `--profile`,
|
||||||
|
`--swap`, `--skip-reboot`.
|
||||||
|
|
||||||
## Configuration
|
## Configuration
|
||||||
|
|
||||||
@@ -145,6 +211,7 @@ Set in `infra/.env`:
|
|||||||
| `PUBLIC_API_URL` / `PUBLIC_LIVEKIT_URL` | Addresses browsers and kiosks use to reach you |
|
| `PUBLIC_API_URL` / `PUBLIC_LIVEKIT_URL` | Addresses browsers and kiosks use to reach you |
|
||||||
| `PUBLIC_WEB_URL` | The address the website is served on. Must match what you type in the browser, scheme included, or server rendered pages disagree with the browser |
|
| `PUBLIC_WEB_URL` | The address the website is served on. Must match what you type in the browser, scheme included, or server rendered pages disagree with the browser |
|
||||||
| `CORS_ORIGINS` | Browser origins allowed to call the API, comma separated. Must include `PUBLIC_WEB_URL`. Kiosks are exempt, since a desktop app has no fixed web origin |
|
| `CORS_ORIGINS` | Browser origins allowed to call the API, comma separated. Must include `PUBLIC_WEB_URL`. Kiosks are exempt, since a desktop app has no fixed web origin |
|
||||||
|
| `TLS_WEB_PORT` / `TLS_API_PORT` / `TLS_LIVEKIT_PORT` | Ports the `tls` profile serves HTTPS on, defaulting to 3443, 8443 and 7443 |
|
||||||
|
|
||||||
Video encoding on the kiosk is tunable per device, without rebuilding:
|
Video encoding on the kiosk is tunable per device, without rebuilding:
|
||||||
|
|
||||||
|
|||||||
@@ -5,6 +5,10 @@ PUBLIC_LIVEKIT_URL=ws://localhost:7880
|
|||||||
PUBLIC_API_URL=http://localhost:8080
|
PUBLIC_API_URL=http://localhost:8080
|
||||||
PUBLIC_WEB_URL=http://localhost:3000
|
PUBLIC_WEB_URL=http://localhost:3000
|
||||||
|
|
||||||
|
TLS_WEB_PORT=3443
|
||||||
|
TLS_API_PORT=8443
|
||||||
|
TLS_LIVEKIT_PORT=7443
|
||||||
|
|
||||||
SESSION_SECRET=change-me-to-a-long-random-string
|
SESSION_SECRET=change-me-to-a-long-random-string
|
||||||
SESSION_TTL_HOURS=12
|
SESSION_TTL_HOURS=12
|
||||||
|
|
||||||
|
|||||||
Executable
+194
@@ -0,0 +1,194 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||||
|
ENV_FILE="$SCRIPT_DIR/.env"
|
||||||
|
OUT_DIR="$SCRIPT_DIR/certs"
|
||||||
|
LEAF_DAYS=825
|
||||||
|
CA_DAYS=3650
|
||||||
|
NEW_CA="no"
|
||||||
|
EXTRA_HOSTS=()
|
||||||
|
|
||||||
|
log() { printf '\033[1;34m==>\033[0m %s\n' "$*"; }
|
||||||
|
warn() { printf '\033[1;33m==>\033[0m %s\n' "$*" >&2; }
|
||||||
|
fail() { printf '\033[1;31m==>\033[0m %s\n' "$*" >&2; exit 1; }
|
||||||
|
|
||||||
|
usage() {
|
||||||
|
cat <<'USAGE'
|
||||||
|
PiStation self signed certificates
|
||||||
|
|
||||||
|
./infra/certs.sh [options]
|
||||||
|
|
||||||
|
Creates a local certificate authority and a server certificate covering every
|
||||||
|
address in your .env, so browsers treat the site as secure and allow camera and
|
||||||
|
screen sharing. Install certs/ca.crt on each device once and every PiStation
|
||||||
|
address is trusted.
|
||||||
|
|
||||||
|
Options
|
||||||
|
--env <file> Read addresses from this file, defaults to infra/.env
|
||||||
|
--out <dir> Write certificates here, defaults to infra/certs
|
||||||
|
--host <name> Cover an extra hostname or IP, repeatable
|
||||||
|
--days <n> How long the server certificate lasts, defaults to 825
|
||||||
|
--new-ca Replace the authority instead of reusing it
|
||||||
|
--help Show this message
|
||||||
|
USAGE
|
||||||
|
}
|
||||||
|
|
||||||
|
while [[ $# -gt 0 ]]; do
|
||||||
|
case "$1" in
|
||||||
|
--env) ENV_FILE="${2:-}"; shift 2 ;;
|
||||||
|
--env=*) ENV_FILE="${1#*=}"; shift ;;
|
||||||
|
--out) OUT_DIR="${2:-}"; shift 2 ;;
|
||||||
|
--out=*) OUT_DIR="${1#*=}"; shift ;;
|
||||||
|
--host) EXTRA_HOSTS+=("${2:-}"); shift 2 ;;
|
||||||
|
--host=*) EXTRA_HOSTS+=("${1#*=}"); shift ;;
|
||||||
|
--days) LEAF_DAYS="${2:-}"; shift 2 ;;
|
||||||
|
--days=*) LEAF_DAYS="${1#*=}"; shift ;;
|
||||||
|
--new-ca) NEW_CA="yes"; shift ;;
|
||||||
|
--help|-h) usage; exit 0 ;;
|
||||||
|
*) fail "unknown option: $1" ;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
|
command -v openssl >/dev/null 2>&1 || fail "openssl is not installed"
|
||||||
|
|
||||||
|
env_value() {
|
||||||
|
[[ -f "$ENV_FILE" ]] || return 0
|
||||||
|
sed -n "s/^[[:space:]]*$1[[:space:]]*=[[:space:]]*//p" "$ENV_FILE" |
|
||||||
|
tail -n 1 |
|
||||||
|
tr -d '"'"'"'\r'
|
||||||
|
}
|
||||||
|
|
||||||
|
url_host() {
|
||||||
|
local value="${1#*://}"
|
||||||
|
value="${value%%/*}"
|
||||||
|
value="${value%%\?*}"
|
||||||
|
printf '%s' "${value%%:*}"
|
||||||
|
}
|
||||||
|
|
||||||
|
lan_address() {
|
||||||
|
ip -4 route get 1.1.1.1 2>/dev/null | sed -n 's/.*src \([0-9.]*\).*/\1/p' | head -n 1
|
||||||
|
}
|
||||||
|
|
||||||
|
is_ip() {
|
||||||
|
[[ "$1" =~ ^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+$ ]]
|
||||||
|
}
|
||||||
|
|
||||||
|
HOSTS=(localhost 127.0.0.1)
|
||||||
|
|
||||||
|
add_host() {
|
||||||
|
local candidate="$1"
|
||||||
|
[[ -n "$candidate" ]] || return 0
|
||||||
|
local existing
|
||||||
|
for existing in "${HOSTS[@]}"; do
|
||||||
|
[[ "$existing" == "$candidate" ]] && return 0
|
||||||
|
done
|
||||||
|
HOSTS+=("$candidate")
|
||||||
|
}
|
||||||
|
|
||||||
|
PRIMARY=""
|
||||||
|
|
||||||
|
for key in PUBLIC_WEB_URL PUBLIC_API_URL PUBLIC_LIVEKIT_URL; do
|
||||||
|
host="$(url_host "$(env_value "$key")")"
|
||||||
|
[[ -n "$host" ]] || continue
|
||||||
|
[[ -n "$PRIMARY" || "$host" == "localhost" ]] || PRIMARY="$host"
|
||||||
|
add_host "$host"
|
||||||
|
done
|
||||||
|
|
||||||
|
for host in ${EXTRA_HOSTS[@]+"${EXTRA_HOSTS[@]}"}; do
|
||||||
|
[[ -n "$PRIMARY" ]] || PRIMARY="$host"
|
||||||
|
add_host "$host"
|
||||||
|
done
|
||||||
|
|
||||||
|
add_host "$(lan_address)"
|
||||||
|
|
||||||
|
if [[ -z "$PRIMARY" ]]; then
|
||||||
|
PRIMARY="$(lan_address)"
|
||||||
|
[[ -n "$PRIMARY" ]] || PRIMARY="localhost"
|
||||||
|
warn "no LAN address found in $ENV_FILE, falling back to $PRIMARY"
|
||||||
|
fi
|
||||||
|
|
||||||
|
mkdir -p "$OUT_DIR"
|
||||||
|
|
||||||
|
CA_KEY="$OUT_DIR/ca.key"
|
||||||
|
CA_CRT="$OUT_DIR/ca.crt"
|
||||||
|
LEAF_KEY="$OUT_DIR/pistation.key"
|
||||||
|
LEAF_CRT="$OUT_DIR/pistation.crt"
|
||||||
|
|
||||||
|
if [[ "$NEW_CA" == "yes" || ! -f "$CA_KEY" || ! -f "$CA_CRT" ]]; then
|
||||||
|
log "creating certificate authority"
|
||||||
|
openssl req -x509 -newkey rsa:4096 -sha256 -nodes \
|
||||||
|
-days "$CA_DAYS" \
|
||||||
|
-keyout "$CA_KEY" \
|
||||||
|
-out "$CA_CRT" \
|
||||||
|
-subj "/CN=PiStation Local CA/O=PiStation" \
|
||||||
|
-addext "basicConstraints=critical,CA:TRUE,pathlen:0" \
|
||||||
|
-addext "keyUsage=critical,keyCertSign,cRLSign" >/dev/null 2>&1
|
||||||
|
else
|
||||||
|
log "reusing certificate authority at $CA_CRT"
|
||||||
|
fi
|
||||||
|
|
||||||
|
WORK_DIR="$(mktemp -d)"
|
||||||
|
trap 'rm -rf "$WORK_DIR"' EXIT
|
||||||
|
|
||||||
|
{
|
||||||
|
printf '[req]\ndistinguished_name = dn\nprompt = no\n\n[dn]\nCN = %s\nO = PiStation\n\n' "$PRIMARY"
|
||||||
|
printf '[ext]\nbasicConstraints = critical, CA:FALSE\n'
|
||||||
|
printf 'keyUsage = critical, digitalSignature, keyEncipherment\n'
|
||||||
|
printf 'extendedKeyUsage = serverAuth\nsubjectAltName = @alt\n\n[alt]\n'
|
||||||
|
|
||||||
|
dns_index=0
|
||||||
|
ip_index=0
|
||||||
|
for host in "${HOSTS[@]}"; do
|
||||||
|
if is_ip "$host"; then
|
||||||
|
ip_index=$((ip_index + 1))
|
||||||
|
printf 'IP.%d = %s\n' "$ip_index" "$host"
|
||||||
|
else
|
||||||
|
dns_index=$((dns_index + 1))
|
||||||
|
printf 'DNS.%d = %s\n' "$dns_index" "$host"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
} >"$WORK_DIR/leaf.cnf"
|
||||||
|
|
||||||
|
log "issuing certificate for $PRIMARY"
|
||||||
|
openssl genrsa -out "$LEAF_KEY" 2048 >/dev/null 2>&1
|
||||||
|
openssl req -new -key "$LEAF_KEY" -out "$WORK_DIR/leaf.csr" -config "$WORK_DIR/leaf.cnf" >/dev/null 2>&1
|
||||||
|
openssl x509 -req -sha256 \
|
||||||
|
-in "$WORK_DIR/leaf.csr" \
|
||||||
|
-CA "$CA_CRT" \
|
||||||
|
-CAkey "$CA_KEY" \
|
||||||
|
-CAcreateserial \
|
||||||
|
-days "$LEAF_DAYS" \
|
||||||
|
-extfile "$WORK_DIR/leaf.cnf" \
|
||||||
|
-extensions ext \
|
||||||
|
-out "$WORK_DIR/leaf.crt" >/dev/null 2>&1
|
||||||
|
|
||||||
|
cat "$WORK_DIR/leaf.crt" "$CA_CRT" >"$LEAF_CRT"
|
||||||
|
chmod 600 "$CA_KEY" "$LEAF_KEY"
|
||||||
|
chmod 644 "$CA_CRT" "$LEAF_CRT"
|
||||||
|
|
||||||
|
WEB_PORT="$(env_value TLS_WEB_PORT)"
|
||||||
|
API_PORT="$(env_value TLS_API_PORT)"
|
||||||
|
LIVEKIT_PORT="$(env_value TLS_LIVEKIT_PORT)"
|
||||||
|
WEB_PORT="${WEB_PORT:-3443}"
|
||||||
|
API_PORT="${API_PORT:-8443}"
|
||||||
|
LIVEKIT_PORT="${LIVEKIT_PORT:-7443}"
|
||||||
|
|
||||||
|
log "done, valid for $LEAF_DAYS days"
|
||||||
|
echo
|
||||||
|
echo " covers: ${HOSTS[*]}"
|
||||||
|
echo
|
||||||
|
echo "Start the stack with TLS:"
|
||||||
|
echo
|
||||||
|
echo " docker compose -f infra/docker-compose.yml --profile tls up -d"
|
||||||
|
echo
|
||||||
|
echo "Then point $ENV_FILE at the encrypted ports:"
|
||||||
|
echo
|
||||||
|
echo " PUBLIC_WEB_URL=https://${PRIMARY}:${WEB_PORT}"
|
||||||
|
echo " PUBLIC_API_URL=https://${PRIMARY}:${API_PORT}"
|
||||||
|
echo " PUBLIC_LIVEKIT_URL=wss://${PRIMARY}:${LIVEKIT_PORT}"
|
||||||
|
echo " CORS_ORIGINS=https://${PRIMARY}:${WEB_PORT},http://localhost:3000,http://localhost:5173"
|
||||||
|
echo
|
||||||
|
echo "Install $CA_CRT on every device that connects, otherwise the browser"
|
||||||
|
echo "keeps warning and still refuses the camera."
|
||||||
|
echo
|
||||||
@@ -55,5 +55,23 @@ services:
|
|||||||
ports:
|
ports:
|
||||||
- "3000:3000"
|
- "3000:3000"
|
||||||
|
|
||||||
|
proxy:
|
||||||
|
image: nginx:alpine
|
||||||
|
restart: unless-stopped
|
||||||
|
profiles:
|
||||||
|
- tls
|
||||||
|
depends_on:
|
||||||
|
- server
|
||||||
|
- web
|
||||||
|
volumes:
|
||||||
|
- ./proxy.conf:/etc/nginx/conf.d/pistation.conf:ro
|
||||||
|
- ./certs:/etc/nginx/certs:ro
|
||||||
|
extra_hosts:
|
||||||
|
- "host.docker.internal:host-gateway"
|
||||||
|
ports:
|
||||||
|
- "${TLS_WEB_PORT:-3443}:3443"
|
||||||
|
- "${TLS_API_PORT:-8443}:8443"
|
||||||
|
- "${TLS_LIVEKIT_PORT:-7443}:7443"
|
||||||
|
|
||||||
volumes:
|
volumes:
|
||||||
server-data:
|
server-data:
|
||||||
|
|||||||
@@ -0,0 +1,49 @@
|
|||||||
|
map $http_upgrade $connection_upgrade {
|
||||||
|
default upgrade;
|
||||||
|
'' close;
|
||||||
|
}
|
||||||
|
|
||||||
|
ssl_certificate /etc/nginx/certs/pistation.crt;
|
||||||
|
ssl_certificate_key /etc/nginx/certs/pistation.key;
|
||||||
|
ssl_protocols TLSv1.2 TLSv1.3;
|
||||||
|
ssl_session_cache shared:pistation:4m;
|
||||||
|
|
||||||
|
client_max_body_size 0;
|
||||||
|
proxy_http_version 1.1;
|
||||||
|
proxy_set_header Host $http_host;
|
||||||
|
proxy_set_header X-Real-IP $remote_addr;
|
||||||
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||||
|
proxy_set_header X-Forwarded-Proto https;
|
||||||
|
proxy_set_header Upgrade $http_upgrade;
|
||||||
|
proxy_set_header Connection $connection_upgrade;
|
||||||
|
proxy_read_timeout 1h;
|
||||||
|
proxy_send_timeout 1h;
|
||||||
|
|
||||||
|
server {
|
||||||
|
listen 3443 ssl;
|
||||||
|
http2 on;
|
||||||
|
server_name _;
|
||||||
|
|
||||||
|
location / {
|
||||||
|
proxy_pass http://web:3000;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
server {
|
||||||
|
listen 8443 ssl;
|
||||||
|
http2 on;
|
||||||
|
server_name _;
|
||||||
|
|
||||||
|
location / {
|
||||||
|
proxy_pass http://server:8080;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
server {
|
||||||
|
listen 7443 ssl;
|
||||||
|
server_name _;
|
||||||
|
|
||||||
|
location / {
|
||||||
|
proxy_pass http://host.docker.internal:7880;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -6,6 +6,7 @@ PACKAGE_URL=""
|
|||||||
ENROLLMENT_KEY=""
|
ENROLLMENT_KEY=""
|
||||||
JOIN_URL=""
|
JOIN_URL=""
|
||||||
KIOSK_USER="pistation"
|
KIOSK_USER="pistation"
|
||||||
|
CA_CERT=""
|
||||||
SKIP_REBOOT="no"
|
SKIP_REBOOT="no"
|
||||||
FORCED_PROFILE=""
|
FORCED_PROFILE=""
|
||||||
FORCED_SWAP=""
|
FORCED_SWAP=""
|
||||||
@@ -26,6 +27,7 @@ Options
|
|||||||
--join-url <host> Address shown on screen for people joining, defaults to the server host
|
--join-url <host> Address shown on screen for people joining, defaults to the server host
|
||||||
--package-url <url> Override where the kiosk .deb is downloaded from
|
--package-url <url> Override where the kiosk .deb is downloaded from
|
||||||
--user <name> System user to run the kiosk as, defaults to pistation
|
--user <name> System user to run the kiosk as, defaults to pistation
|
||||||
|
--ca-cert <path|url> Trust this certificate authority, needed for a self signed server
|
||||||
--profile <name> Force a video profile: zero2, pi4, pi5 or generic
|
--profile <name> Force a video profile: zero2, pi4, pi5 or generic
|
||||||
--swap <mb> Swap size in MB, defaults to the profile's value
|
--swap <mb> Swap size in MB, defaults to the profile's value
|
||||||
--skip-reboot Install and enable, but do not reboot at the end
|
--skip-reboot Install and enable, but do not reboot at the end
|
||||||
@@ -45,6 +47,8 @@ while [[ $# -gt 0 ]]; do
|
|||||||
--package-url=*) PACKAGE_URL="${1#*=}"; shift ;;
|
--package-url=*) PACKAGE_URL="${1#*=}"; shift ;;
|
||||||
--user) KIOSK_USER="${2:-}"; shift 2 ;;
|
--user) KIOSK_USER="${2:-}"; shift 2 ;;
|
||||||
--user=*) KIOSK_USER="${1#*=}"; shift ;;
|
--user=*) KIOSK_USER="${1#*=}"; shift ;;
|
||||||
|
--ca-cert) CA_CERT="${2:-}"; shift 2 ;;
|
||||||
|
--ca-cert=*) CA_CERT="${1#*=}"; shift ;;
|
||||||
--profile) FORCED_PROFILE="${2:-}"; shift 2 ;;
|
--profile) FORCED_PROFILE="${2:-}"; shift 2 ;;
|
||||||
--profile=*) FORCED_PROFILE="${1#*=}"; shift ;;
|
--profile=*) FORCED_PROFILE="${1#*=}"; shift ;;
|
||||||
--swap) FORCED_SWAP="${2:-}"; shift 2 ;;
|
--swap) FORCED_SWAP="${2:-}"; shift 2 ;;
|
||||||
@@ -150,6 +154,24 @@ apt-get install -y --no-install-recommends \
|
|||||||
libnice10 \
|
libnice10 \
|
||||||
libgles2
|
libgles2
|
||||||
|
|
||||||
|
# A kiosk has nobody to click through a certificate warning, so a self signed server has to be
|
||||||
|
# trusted here or every request it makes fails, starting with the package download below.
|
||||||
|
if [[ -n "$CA_CERT" ]]; then
|
||||||
|
log "trusting the certificate authority at $CA_CERT"
|
||||||
|
CA_TARGET="/usr/local/share/ca-certificates/pistation-ca.crt"
|
||||||
|
|
||||||
|
if [[ "$CA_CERT" == http://* || "$CA_CERT" == https://* ]]; then
|
||||||
|
curl -fsSL "$CA_CERT" -o "$CA_TARGET" ||
|
||||||
|
fail "could not download the certificate authority from $CA_CERT"
|
||||||
|
else
|
||||||
|
[[ -f "$CA_CERT" ]] || fail "no certificate authority at $CA_CERT"
|
||||||
|
cp "$CA_CERT" "$CA_TARGET"
|
||||||
|
fi
|
||||||
|
|
||||||
|
chmod 644 "$CA_TARGET"
|
||||||
|
update-ca-certificates >/dev/null || fail "the certificate authority was rejected"
|
||||||
|
fi
|
||||||
|
|
||||||
log "downloading the kiosk package from $PACKAGE_URL"
|
log "downloading the kiosk package from $PACKAGE_URL"
|
||||||
PACKAGE_FILE="$(mktemp /tmp/pistation-kiosk.XXXXXX.deb)"
|
PACKAGE_FILE="$(mktemp /tmp/pistation-kiosk.XXXXXX.deb)"
|
||||||
trap 'rm -f "$PACKAGE_FILE"' EXIT
|
trap 'rm -f "$PACKAGE_FILE"' EXIT
|
||||||
|
|||||||
Reference in New Issue
Block a user