Lockdown intranet services behind tailscale
This commit is contained in:
parent
4d658e10d3
commit
d557820d6c
@ -37,17 +37,5 @@ in
|
|||||||
];
|
];
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
services.nginx.enable = true;
|
|
||||||
services.nginx.virtualHosts."s0.koi-bebop.ts.net" = {
|
|
||||||
default = true;
|
|
||||||
addSSL = true;
|
|
||||||
serverAliases = [ "s0" ];
|
|
||||||
sslCertificate = "/secret/ssl/s0.koi-bebop.ts.net.crt";
|
|
||||||
sslCertificateKey = "/secret/ssl/s0.koi-bebop.ts.net.key";
|
|
||||||
locations."/" = {
|
|
||||||
proxyPass = "http://localhost:${toString cfg.port}";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -22,5 +22,6 @@
|
|||||||
./dashy.nix
|
./dashy.nix
|
||||||
./librechat.nix
|
./librechat.nix
|
||||||
./actualbudget.nix
|
./actualbudget.nix
|
||||||
|
./unifi.nix
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
@ -4,6 +4,10 @@ let
|
|||||||
cfg = config.services.nginx;
|
cfg = config.services.nginx;
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
|
options.services.nginx = {
|
||||||
|
openFirewall = lib.mkEnableOption "Open firewall ports 80 and 443";
|
||||||
|
};
|
||||||
|
|
||||||
config = lib.mkIf cfg.enable {
|
config = lib.mkIf cfg.enable {
|
||||||
services.nginx = {
|
services.nginx = {
|
||||||
recommendedGzipSettings = true;
|
recommendedGzipSettings = true;
|
||||||
@ -12,6 +16,8 @@ in
|
|||||||
recommendedTlsSettings = true;
|
recommendedTlsSettings = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
networking.firewall.allowedTCPPorts = [ 80 443 ];
|
services.nginx.openFirewall = lib.mkDefault true;
|
||||||
|
|
||||||
|
networking.firewall.allowedTCPPorts = lib.mkIf cfg.openFirewall [ 80 443 ];
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
25
common/server/unifi.nix
Normal file
25
common/server/unifi.nix
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
{ config, lib, pkgs, ... }:
|
||||||
|
|
||||||
|
let
|
||||||
|
cfg = config.services.unifi;
|
||||||
|
in
|
||||||
|
{
|
||||||
|
options.services.unifi = {
|
||||||
|
# Open select Unifi ports instead of using openFirewall to avoid opening access to unifi's control panel
|
||||||
|
openMinimalFirewall = lib.mkEnableOption "Open bare minimum firewall ports";
|
||||||
|
};
|
||||||
|
|
||||||
|
config = lib.mkIf cfg.enable {
|
||||||
|
services.unifi.unifiPackage = pkgs.unifi8;
|
||||||
|
|
||||||
|
networking.firewall = lib.mkIf cfg.openMinimalFirewall {
|
||||||
|
allowedUDPPorts = [
|
||||||
|
3478 # STUN
|
||||||
|
10001 # used for device discovery.
|
||||||
|
];
|
||||||
|
allowedTCPPorts = [
|
||||||
|
8080 # Used for device and application communication.
|
||||||
|
];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
@ -118,14 +118,6 @@
|
|||||||
|
|
||||||
# proxied web services
|
# proxied web services
|
||||||
services.nginx.enable = true;
|
services.nginx.enable = true;
|
||||||
services.nginx.virtualHosts."jellyfin.neet.cloud" = {
|
|
||||||
enableACME = true;
|
|
||||||
forceSSL = true;
|
|
||||||
locations."/" = {
|
|
||||||
proxyPass = "http://s0.koi-bebop.ts.net";
|
|
||||||
proxyWebsockets = true;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
services.nginx.virtualHosts."navidrome.neet.cloud" = {
|
services.nginx.virtualHosts."navidrome.neet.cloud" = {
|
||||||
enableACME = true;
|
enableACME = true;
|
||||||
forceSSL = true;
|
forceSSL = true;
|
||||||
|
@ -60,73 +60,65 @@ sections:
|
|||||||
- &ref_0
|
- &ref_0
|
||||||
title: Jellyfin
|
title: Jellyfin
|
||||||
icon: hl-jellyfin
|
icon: hl-jellyfin
|
||||||
url: http://s0:8097
|
url: https://jellyfin.s0.neet.dev
|
||||||
target: sametab
|
target: sametab
|
||||||
statusCheck: true
|
statusCheck: false
|
||||||
statusCheckUrl: http://jellyfin.s0
|
|
||||||
id: 0_1956_jellyfin
|
id: 0_1956_jellyfin
|
||||||
- &ref_1
|
- &ref_1
|
||||||
title: Sonarr
|
title: Sonarr
|
||||||
description: Manage TV
|
description: Manage TV
|
||||||
icon: hl-sonarr
|
icon: hl-sonarr
|
||||||
url: http://s0:8989
|
url: https://sonarr.s0.neet.dev
|
||||||
target: sametab
|
target: sametab
|
||||||
statusCheck: true
|
statusCheck: false
|
||||||
statusCheckUrl: http://sonarr.s0
|
|
||||||
id: 1_1956_sonarr
|
id: 1_1956_sonarr
|
||||||
- &ref_2
|
- &ref_2
|
||||||
title: Radarr
|
title: Radarr
|
||||||
description: Manage Movies
|
description: Manage Movies
|
||||||
icon: hl-radarr
|
icon: hl-radarr
|
||||||
url: http://s0:7878
|
url: https://radarr.s0.neet.dev
|
||||||
target: sametab
|
target: sametab
|
||||||
statusCheck: true
|
statusCheck: false
|
||||||
statusCheckUrl: http://radarr.s0
|
|
||||||
id: 2_1956_radarr
|
id: 2_1956_radarr
|
||||||
- &ref_3
|
- &ref_3
|
||||||
title: Lidarr
|
title: Lidarr
|
||||||
description: Manage Music
|
description: Manage Music
|
||||||
icon: hl-lidarr
|
icon: hl-lidarr
|
||||||
url: http://s0:8686
|
url: https://lidarr.s0.neet.dev
|
||||||
target: sametab
|
target: sametab
|
||||||
statusCheck: true
|
statusCheck: false
|
||||||
statusCheckUrl: http://lidarr.s0
|
|
||||||
id: 3_1956_lidarr
|
id: 3_1956_lidarr
|
||||||
- &ref_4
|
- &ref_4
|
||||||
title: Prowlarr
|
title: Prowlarr
|
||||||
description: Indexers
|
description: Indexers
|
||||||
icon: hl-prowlarr
|
icon: hl-prowlarr
|
||||||
url: http://prowlarr.s0
|
url: https://prowlarr.s0.neet.dev
|
||||||
target: sametab
|
target: sametab
|
||||||
statusCheck: true
|
statusCheck: false
|
||||||
statusCheckUrl: http://prowlarr.s0
|
|
||||||
id: 4_1956_prowlarr
|
id: 4_1956_prowlarr
|
||||||
- &ref_5
|
- &ref_5
|
||||||
title: Bazarr
|
title: Bazarr
|
||||||
description: Subtitles
|
description: Subtitles
|
||||||
icon: hl-bazarr
|
icon: hl-bazarr
|
||||||
url: http://s0:6767
|
url: https://bazarr.s0.neet.dev
|
||||||
target: sametab
|
target: sametab
|
||||||
statusCheck: true
|
statusCheck: false
|
||||||
statusCheckUrl: http://bazarr.s0
|
|
||||||
id: 5_1956_bazarr
|
id: 5_1956_bazarr
|
||||||
- &ref_6
|
- &ref_6
|
||||||
title: Navidrome
|
title: Navidrome
|
||||||
description: Play Music
|
description: Play Music
|
||||||
icon: hl-navidrome
|
icon: hl-navidrome
|
||||||
url: http://s0:4534
|
url: https://music.s0.neet.dev
|
||||||
target: sametab
|
target: sametab
|
||||||
statusCheck: true
|
statusCheck: false
|
||||||
statusCheckUrl: http://music.s0
|
|
||||||
id: 6_1956_navidrome
|
id: 6_1956_navidrome
|
||||||
- &ref_7
|
- &ref_7
|
||||||
title: Transmission
|
title: Transmission
|
||||||
description: Torrenting
|
description: Torrenting
|
||||||
icon: hl-transmission
|
icon: hl-transmission
|
||||||
url: http://s0:9091
|
url: https://transmission.s0.neet.dev
|
||||||
target: sametab
|
target: sametab
|
||||||
statusCheck: true
|
statusCheck: false
|
||||||
statusCheckUrl: http://transmission.s0
|
|
||||||
id: 7_1956_transmission
|
id: 7_1956_transmission
|
||||||
filteredItems:
|
filteredItems:
|
||||||
- *ref_0
|
- *ref_0
|
||||||
|
@ -165,61 +165,96 @@
|
|||||||
};
|
};
|
||||||
|
|
||||||
# nginx
|
# nginx
|
||||||
services.nginx.enable = true;
|
services.nginx = {
|
||||||
services.nginx.virtualHosts."bazarr.s0" = {
|
enable = true;
|
||||||
listen = [{ addr = "0.0.0.0"; port = 6767; } { addr = "0.0.0.0"; port = 80; }];
|
openFirewall = false; # All nginx services are internal
|
||||||
locations."/".proxyPass = "http://vpn.containers:6767";
|
virtualHosts =
|
||||||
};
|
let
|
||||||
services.nginx.virtualHosts."radarr.s0" = {
|
mkVirtualHost = external: internal:
|
||||||
listen = [{ addr = "0.0.0.0"; port = 7878; } { addr = "0.0.0.0"; port = 80; }];
|
{
|
||||||
locations."/".proxyPass = "http://vpn.containers:7878";
|
${external} = {
|
||||||
};
|
useACMEHost = "s0.neet.dev"; # Use wildcard cert
|
||||||
services.nginx.virtualHosts."lidarr.s0" = {
|
forceSSL = true;
|
||||||
listen = [{ addr = "0.0.0.0"; port = 8686; } { addr = "0.0.0.0"; port = 80; }];
|
locations."/" = {
|
||||||
locations."/".proxyPass = "http://vpn.containers:8686";
|
proxyPass = internal;
|
||||||
};
|
proxyWebsockets = true;
|
||||||
services.nginx.virtualHosts."sonarr.s0" = {
|
};
|
||||||
listen = [{ addr = "0.0.0.0"; port = 8989; } { addr = "0.0.0.0"; port = 80; }];
|
};
|
||||||
locations."/".proxyPass = "http://vpn.containers:8989";
|
};
|
||||||
};
|
in
|
||||||
services.nginx.virtualHosts."prowlarr.s0" = {
|
lib.mkMerge [
|
||||||
listen = [{ addr = "0.0.0.0"; port = 9696; } { addr = "0.0.0.0"; port = 80; }];
|
(mkVirtualHost "bazarr.s0.neet.dev" "http://vpn.containers:6767")
|
||||||
locations."/".proxyPass = "http://vpn.containers:9696";
|
(mkVirtualHost "radarr.s0.neet.dev" "http://vpn.containers:7878")
|
||||||
};
|
(mkVirtualHost "lidarr.s0.neet.dev" "http://vpn.containers:8686")
|
||||||
services.nginx.virtualHosts."music.s0" = {
|
(mkVirtualHost "sonarr.s0.neet.dev" "http://vpn.containers:8989")
|
||||||
listen = [{ addr = "0.0.0.0"; port = 4534; } { addr = "0.0.0.0"; port = 80; }];
|
(mkVirtualHost "prowlarr.s0.neet.dev" "http://vpn.containers:9696")
|
||||||
locations."/".proxyPass = "http://localhost:4533";
|
(mkVirtualHost "transmission.s0.neet.dev" "http://vpn.containers:9091")
|
||||||
};
|
(mkVirtualHost "unifi.s0.neet.dev" "https://localhost:8443")
|
||||||
services.nginx.virtualHosts."jellyfin.s0" = {
|
(mkVirtualHost "music.s0.neet.dev" "http://localhost:4533")
|
||||||
listen = [{ addr = "0.0.0.0"; port = 8097; } { addr = "0.0.0.0"; port = 80; }];
|
(mkVirtualHost "jellyfin.s0.neet.dev" "http://localhost:8096")
|
||||||
locations."/" = {
|
(mkVirtualHost "s0.neet.dev" "http://localhost:56815")
|
||||||
proxyPass = "http://localhost:8096";
|
(mkVirtualHost "ha.s0.neet.dev" "http://localhost:8123") # home assistant
|
||||||
proxyWebsockets = true;
|
(mkVirtualHost "esphome.s0.neet.dev" "http://localhost:6052")
|
||||||
};
|
(mkVirtualHost "zigbee.s0.neet.dev" "http://localhost:55834")
|
||||||
};
|
{
|
||||||
services.nginx.virtualHosts."jellyfin.neet.cloud".locations."/" = {
|
# Landing page LAN redirect
|
||||||
proxyPass = "http://localhost:8096";
|
"s0" = {
|
||||||
proxyWebsockets = true;
|
default = true;
|
||||||
};
|
redirectCode = 302;
|
||||||
services.nginx.virtualHosts."transmission.s0" = {
|
globalRedirect = "s0.neet.dev";
|
||||||
listen = [{ addr = "0.0.0.0"; port = 9091; } { addr = "0.0.0.0"; port = 80; }];
|
};
|
||||||
locations."/" = {
|
"frigate.s0.neet.dev" = {
|
||||||
proxyPass = "http://vpn.containers:9091";
|
# Just configure SSL, frigate module configures the rest of nginx
|
||||||
proxyWebsockets = true;
|
useACMEHost = "s0.neet.dev";
|
||||||
|
forceSSL = true;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
# Problem #1: Keeping certain programs from being accessed from certain external networks/VLANs
|
||||||
|
# Solution #1: Isolate that service in a container system that automatically fowards the ports to the right network interface(s)
|
||||||
|
# Solution #2: Don't open the firewall for these services, manually open the ports instead for the specific network interface(s) (trickier and easy to miss ports or ports can change)
|
||||||
|
# Untrusted network list:
|
||||||
|
# - VLANs [cameras]
|
||||||
|
|
||||||
|
# Problem #2: Untrusted internal services. Prevent them from accessing certain internal services (usually key unauth'd services like frigate)
|
||||||
|
# Solution #1: Isolate the untrusted services into their own container
|
||||||
|
# Untrusted services list:
|
||||||
|
# - Unifi? (it already has access to the cameras anyway?)
|
||||||
|
# - torrenting, *arr (worried about vulns)
|
||||||
|
|
||||||
|
|
||||||
|
tailscaleAuth = {
|
||||||
|
enable = true;
|
||||||
|
virtualHosts = [
|
||||||
|
"bazarr.s0.neet.dev"
|
||||||
|
"radarr.s0.neet.dev"
|
||||||
|
"lidarr.s0.neet.dev"
|
||||||
|
"sonarr.s0.neet.dev"
|
||||||
|
"prowlarr.s0.neet.dev"
|
||||||
|
"transmission.s0.neet.dev"
|
||||||
|
"unifi.s0.neet.dev"
|
||||||
|
# "music.s0.neet.dev" # messes up navidrome
|
||||||
|
"jellyfin.s0.neet.dev"
|
||||||
|
"s0.neet.dev"
|
||||||
|
# "ha.s0.neet.dev" # messes up home assistant
|
||||||
|
"esphome.s0.neet.dev"
|
||||||
|
"zigbee.s0.neet.dev"
|
||||||
|
];
|
||||||
|
expectedTailnet = "koi-bebop.ts.net";
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
networking.firewall.allowedTCPPorts = [
|
# Get wildcard cert
|
||||||
6767
|
security.acme.certs."s0.neet.dev" = {
|
||||||
7878
|
dnsProvider = "digitalocean";
|
||||||
8686
|
credentialsFile = "/run/agenix/digitalocean-dns-credentials";
|
||||||
8989
|
extraDomainNames = [ "*.s0.neet.dev" ];
|
||||||
9696
|
group = "nginx";
|
||||||
4534
|
dnsResolver = "1.1.1.1:53";
|
||||||
8097
|
dnsPropagationCheck = false; # sadly this erroneously fails
|
||||||
9091
|
};
|
||||||
8443 # unifi
|
age.secrets.digitalocean-dns-credentials.file = ../../../secrets/digitalocean-dns-credentials.age;
|
||||||
];
|
|
||||||
|
|
||||||
virtualisation.oci-containers.backend = "podman";
|
virtualisation.oci-containers.backend = "podman";
|
||||||
virtualisation.podman.dockerSocket.enable = true; # TODO needed?
|
virtualisation.podman.dockerSocket.enable = true; # TODO needed?
|
||||||
@ -230,8 +265,7 @@
|
|||||||
|
|
||||||
services.unifi = {
|
services.unifi = {
|
||||||
enable = true;
|
enable = true;
|
||||||
openFirewall = true;
|
openMinimalFirewall = true;
|
||||||
unifiPackage = pkgs.unifi8;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
boot.binfmt.emulatedSystems = [ "aarch64-linux" "armv7l-linux" ];
|
boot.binfmt.emulatedSystems = [ "aarch64-linux" "armv7l-linux" ];
|
||||||
|
@ -1,8 +1,7 @@
|
|||||||
{ config, lib, pkgs, ... }:
|
{ config, lib, pkgs, ... }:
|
||||||
|
|
||||||
let
|
let
|
||||||
frigateHostname = "frigate.s0";
|
frigateHostname = "frigate.s0.neet.dev";
|
||||||
frigatePort = 61617;
|
|
||||||
|
|
||||||
mkEsp32Cam = address: {
|
mkEsp32Cam = address: {
|
||||||
ffmpeg = {
|
ffmpeg = {
|
||||||
@ -41,9 +40,6 @@ in
|
|||||||
{
|
{
|
||||||
networking.firewall.allowedTCPPorts = [
|
networking.firewall.allowedTCPPorts = [
|
||||||
# 1883 # mqtt
|
# 1883 # mqtt
|
||||||
55834 # mqtt zigbee frontend
|
|
||||||
frigatePort
|
|
||||||
4180 # oauth proxy
|
|
||||||
];
|
];
|
||||||
|
|
||||||
services.frigate = {
|
services.frigate = {
|
||||||
@ -80,21 +76,7 @@ in
|
|||||||
# Coral PCIe driver
|
# Coral PCIe driver
|
||||||
kernel.enableGasketKernelModule = true;
|
kernel.enableGasketKernelModule = true;
|
||||||
|
|
||||||
# Allow accessing frigate UI on a specific port in addition to by hostname
|
services.esphome.enable = true;
|
||||||
services.nginx.virtualHosts.${frigateHostname} = {
|
|
||||||
listen = [{ addr = "0.0.0.0"; port = frigatePort; } { addr = "0.0.0.0"; port = 80; }];
|
|
||||||
};
|
|
||||||
|
|
||||||
services.esphome = {
|
|
||||||
enable = true;
|
|
||||||
address = "0.0.0.0";
|
|
||||||
openFirewall = true;
|
|
||||||
};
|
|
||||||
# TODO remove after upgrading nixos version
|
|
||||||
systemd.services.esphome.serviceConfig.ProcSubset = lib.mkForce "all";
|
|
||||||
systemd.services.esphome.serviceConfig.ProtectHostname = lib.mkForce false;
|
|
||||||
systemd.services.esphome.serviceConfig.ProtectKernelLogs = lib.mkForce false;
|
|
||||||
systemd.services.esphome.serviceConfig.ProtectKernelTunables = lib.mkForce false;
|
|
||||||
|
|
||||||
# TODO lock down
|
# TODO lock down
|
||||||
services.mosquitto = {
|
services.mosquitto = {
|
||||||
@ -121,7 +103,7 @@ in
|
|||||||
# base_topic = "zigbee2mqtt";
|
# base_topic = "zigbee2mqtt";
|
||||||
};
|
};
|
||||||
frontend = {
|
frontend = {
|
||||||
host = "0.0.0.0";
|
host = "localhost";
|
||||||
port = 55834;
|
port = 55834;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
@ -129,7 +111,6 @@ in
|
|||||||
|
|
||||||
services.home-assistant = {
|
services.home-assistant = {
|
||||||
enable = true;
|
enable = true;
|
||||||
openFirewall = true;
|
|
||||||
configWritable = true;
|
configWritable = true;
|
||||||
extraComponents = [
|
extraComponents = [
|
||||||
"esphome"
|
"esphome"
|
||||||
@ -143,46 +124,15 @@ in
|
|||||||
# Includes dependencies for a basic setup
|
# Includes dependencies for a basic setup
|
||||||
# https://www.home-assistant.io/integrations/default_config/
|
# https://www.home-assistant.io/integrations/default_config/
|
||||||
default_config = { };
|
default_config = { };
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
# TODO need services.oauth2-proxy.cookie.domain ?
|
# Enable reverse proxy support
|
||||||
services.oauth2-proxy =
|
http = {
|
||||||
let
|
use_x_forwarded_for = true;
|
||||||
nextcloudServer = "https://neet.cloud/";
|
trusted_proxies = [
|
||||||
in
|
"127.0.0.1"
|
||||||
{
|
"::1"
|
||||||
enable = true;
|
];
|
||||||
|
|
||||||
httpAddress = "http://0.0.0.0:4180";
|
|
||||||
|
|
||||||
nginx.domain = frigateHostname;
|
|
||||||
# nginx.virtualHosts = [
|
|
||||||
# frigateHostname
|
|
||||||
# ];
|
|
||||||
|
|
||||||
email.domains = [ "*" ];
|
|
||||||
|
|
||||||
cookie.secure = false;
|
|
||||||
|
|
||||||
provider = "nextcloud";
|
|
||||||
|
|
||||||
# redirectURL = "http://s0:4180/oauth2/callback"; # todo forward with nginx?
|
|
||||||
clientID = "4FfhEB2DNzUh6wWhXTjqQQKu3Ibm6TeYpS8TqcHe55PJC1DorE7vBZBELMKDjJ0X";
|
|
||||||
keyFile = "/run/agenix/oauth2-proxy-env";
|
|
||||||
|
|
||||||
loginURL = "${nextcloudServer}/index.php/apps/oauth2/authorize";
|
|
||||||
redeemURL = "${nextcloudServer}/index.php/apps/oauth2/api/v1/token";
|
|
||||||
validateURL = "${nextcloudServer}/ocs/v2.php/cloud/user?format=json";
|
|
||||||
|
|
||||||
# todo --cookie-refresh
|
|
||||||
|
|
||||||
extraConfig = {
|
|
||||||
# cookie-csrf-per-request = true;
|
|
||||||
# cookie-csrf-expire = "5m";
|
|
||||||
# user-id-claim = "preferred_username";
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
};
|
||||||
age.secrets.oauth2-proxy-env.file = ../../../secrets/oauth2-proxy-env.age;
|
|
||||||
}
|
}
|
||||||
|
11
secrets/digitalocean-dns-credentials.age
Normal file
11
secrets/digitalocean-dns-credentials.age
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
age-encryption.org/v1
|
||||||
|
-> ssh-ed25519 WBT1Hw wjZGPvilRXGZsC2+7dWm/Nbau8Allv29WwQCr0XSAWU
|
||||||
|
uTOf/sokutOGDyc8fbTbBWXqCVQCFhGdHxwA6SXqhdA
|
||||||
|
-> ssh-ed25519 6AT2/g NU068qwqOWiKk0QwqP9vU4xJaND2OR4bo8xkmdWATgY
|
||||||
|
uGd0sb5PH+rREn9pgLOFwk29CX66aPBQMvr4rBazylc
|
||||||
|
-> ssh-ed25519 hPp1nw r2JRiZ7fsHPYDlte6Oh2Gx1KkugekFeeg3xSjziI+hQ
|
||||||
|
xnO0gscMdR25mj5uAX7D42FCbCQhqbU0wkiLX4OmVqk
|
||||||
|
-> ssh-ed25519 w3nu8g F03mPU63WwEs1SLUFErLOVCkARoggGIvvz9TFZfMOBY
|
||||||
|
HOdVA3xW9pqUPhclO6VueSfXg3ux06Ch3fucF6Vr4hM
|
||||||
|
--- niyo231HPT/+2dzflP+zhYjL9XiWsk7svesCYdkU1jA
|
||||||
|
DÑØQî¬5–-ô@<40>¢¿—ßÐN5<4E> Ãÿ$Ø‚™’Çž…êÐ<C3AA>X=ŒHŽDÁ`P×5ZA´÷¼YóäÓ?¡é^[³1”6ÕK*mP݈ªæ1æç÷ß›ƒ:$^ÑfDœ*î†ÿ“š-zi´"·Tàuÿüò
|
@ -51,4 +51,7 @@ with roles;
|
|||||||
|
|
||||||
# Librechat
|
# Librechat
|
||||||
"librechat-env-file.age".publicKeys = librechat;
|
"librechat-env-file.age".publicKeys = librechat;
|
||||||
|
|
||||||
|
# For ACME DNS Challenge
|
||||||
|
"digitalocean-dns-credentials.age".publicKeys = server;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user