This commit is contained in:
Ellie 2026-04-01 14:20:27 -07:00
parent b90f98eb64
commit 8fd56d0f3a
5 changed files with 165 additions and 0 deletions

View file

@ -86,6 +86,8 @@
./services/nginx.nix
./services/blog.nix
./services/coturn.nix
./services/livekit.nix
./services/lk-jwt.nix
./services/wireguard-outer.nix
./services/borgbackup-vps.nix
];

59
services/livekit.nix Normal file
View file

@ -0,0 +1,59 @@
{ config, pkgs, ... }:
{
sops.secrets."livekit/api_key" = {
sopsFile = ./secrets/livekit_vps.yaml;
mode = "0400";
};
sops.secrets."livekit/api_secret" = {
sopsFile = ./secrets/livekit_vps.yaml;
mode = "0400";
};
# WebRTC media (UDP) and ICE TCP fallback. HTTP signaling goes through nginx.
networking.firewall = {
allowedTCPPorts = [ 7881 ];
allowedUDPPortRanges = [
{
from = 50000;
to = 50200;
}
];
};
systemd.services.livekit = {
description = "LiveKit SFU server";
wantedBy = [ "multi-user.target" ];
after = [ "network-online.target" ];
wants = [ "network-online.target" ];
serviceConfig = {
DynamicUser = true;
RuntimeDirectory = "livekit";
Restart = "always";
RestartSec = 5;
};
script = ''
API_KEY=$(cat ${config.sops.secrets."livekit/api_key".path})
API_SECRET=$(cat ${config.sops.secrets."livekit/api_secret".path})
cat > /run/livekit/config.yaml <<YAML
port: 7880
bind_addresses:
- "127.0.0.1"
rtc:
port_range_start: 50000
port_range_end: 50200
use_external_ip: true
tcp_port: 7881
logging:
level: info
keys:
$API_KEY: $API_SECRET
YAML
exec ${pkgs.livekit}/bin/livekit-server --config /run/livekit/config.yaml
'';
};
}

53
services/lk-jwt.nix Normal file
View file

@ -0,0 +1,53 @@
{ config, pkgs, lib, ... }:
let
# lk-jwt-service isn't in nixpkgs — build from source.
# On first `nix build`, the fake hashes will fail and print the correct ones.
lk-jwt-service = pkgs.buildGoModule {
pname = "lk-jwt-service";
version = "0.3.0";
src = pkgs.fetchFromGitHub {
owner = "element-hq";
repo = "lk-jwt-service";
rev = "v0.3.0";
hash = "sha256-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=";
};
vendorHash = "sha256-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=";
meta.mainProgram = "lk-jwt-service";
};
in
{
sops.secrets."livekit/api_key" = {
sopsFile = ./secrets/livekit_vps.yaml;
mode = "0400";
};
sops.secrets."livekit/api_secret" = {
sopsFile = ./secrets/livekit_vps.yaml;
mode = "0400";
};
systemd.services.lk-jwt = {
description = "LiveKit JWT service for Matrix OpenID token exchange";
wantedBy = [ "multi-user.target" ];
after = [
"network-online.target"
"livekit.service"
];
wants = [ "network-online.target" ];
serviceConfig = {
DynamicUser = true;
Restart = "always";
RestartSec = 5;
};
script = ''
export LIVEKIT_URL="wss://livekit.ellie.town"
export LIVEKIT_KEY=$(cat ${config.sops.secrets."livekit/api_key".path})
export LIVEKIT_SECRET=$(cat ${config.sops.secrets."livekit/api_secret".path})
export LK_JWT_PORT=8080
exec ${lk-jwt-service}/bin/lk-jwt-service
'';
};
}

View file

@ -0,0 +1,18 @@
livekit:
api_key: ENC[AES256_GCM,data:zD2FsmXwMR6A,iv:lPkUgWv6lmBsE6ASJbLkF99AhhOZXw/fjEDgehvdmKs=,tag:OfnqmoXJM/hVuNo1Iv5eew==,type:str]
api_secret: ENC[AES256_GCM,data:HwBLo3/BfMnMtkyYHUYGtCXvZ+IHwQX22otrfVe9895dQR45QgMTJfMDogE=,iv:xyqh45uZdLza+zQURnfaAAtS+hGKrDcVF3nL8TFFtus=,tag:btA+bHwVKwzX71mqZvzfKA==,type:str]
sops:
age:
- recipient: age1856wmagg3dz4j07alwqnn6d75655t6wcs8glklyjyezhu5p875fq9sez4p
enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSA0d1VYdWI0TEZtaStvUml6
NEdYS0gvbUlMTVRpY2xna3BRT2ZINkpLZG53CkNrcDNHUjc4Zm43NnhJKzc0UjBX
RTVrQ3hYWFVzdlJ5Zkh6ZWJkZi9CZUEKLS0tIDZuUjNQWmJXSlZqdGQySXNKV3F1
UXNYWktWUktGQWhpeThvOUFNUlFHWGcKvoGymssPBN5yQwpq2HTHYeNt5VnA1pKe
fyJ0mbwMq+/ZW88HE4vpUY8zONC0QCGprxysMVgsRpXFBfFKk0pjcQ==
-----END AGE ENCRYPTED FILE-----
lastmodified: "2026-04-01T21:18:12Z"
mac: ENC[AES256_GCM,data:E4NwepDYNcwhusfuRFebEXyGQcwlhfvddMDWF3JfUAOERvZnmmY5+OMQc/qbF114r3UYvZr3qX1WgsFE4n4YiuGPFY+E5m4/6PV//Lwe4p5GWGto1fPMN7n2jB+Y1RJn+wP18pjvrIc9onaSgiOuP8eFijp1vZ6hX7kZ2lrEdrI=,iv:SP235ndbodZlpv+RwIKw/U6+XyDwJhjfF53pROWMlI0=,tag:4cWULyYdnJKyjxk+7bkkQg==,type:str]
unencrypted_suffix: _unencrypted
version: 3.12.1

View file

@ -60,6 +60,34 @@
};
};
virtualHosts."livekit.ellie.town" = {
enableACME = true;
forceSSL = true;
locations."/" = {
proxyPass = "http://127.0.0.1:7880";
proxyWebsockets = true;
extraConfig = ''
proxy_read_timeout 86400;
'';
};
};
virtualHosts."lk-jwt.ellie.town" = {
enableACME = true;
forceSSL = true;
locations."/" = {
proxyPass = "http://127.0.0.1:8080";
extraConfig = ''
add_header Access-Control-Allow-Origin * always;
add_header Access-Control-Allow-Methods "POST, OPTIONS" always;
add_header Access-Control-Allow-Headers "Content-Type, Authorization" always;
if ($request_method = OPTIONS) {
return 204;
}
'';
};
};
# virtualHosts."akkoma.ellie.town" = {
# enableACME = true;
# forceSSL = true;
@ -131,6 +159,11 @@
default_type application/json;
add_header Access-Control-Allow-Origin *;
return 200 '{"m.homeserver":{"base_url":"https://matrix.ellie.town"}}';'';
locations."= /.well-known/element/call.json".extraConfig = ''
default_type application/json;
add_header Access-Control-Allow-Origin *;
return 200 '{"type":"livekit","livekit_service_url":"https://lk-jwt.ellie.town"}';'';
};
};