commit 29cf56fdd2481bbb2be5b6c7b4855e7a82d47316
Author: Coder Agent <coder@agents.omni>
Date: Thu Feb 19 16:16:37 2026
Migrate beryllium from Tailscale Funnel to Headscale ingress
Task-Id: t-437
diff --git a/Omni/Dev/Beryllium.nix b/Omni/Dev/Beryllium.nix
index a26d7250..163d3f6a 100755
--- a/Omni/Dev/Beryllium.nix
+++ b/Omni/Dev/Beryllium.nix
@@ -18,7 +18,6 @@ in
../Syncthing.nix
../Deploy/Deployer.nix
./Beryllium/Samba.nix
- ./Beryllium/Caddy.nix
];
networking.hostName = "beryllium";
networking.domain = "beryl.bensima.com";
@@ -30,6 +29,6 @@ in
enable = true;
package = packages.deployer;
manifestPackage = packages.deploy-manifest;
- enableCaddy = false; # Ava uses Tailscale Funnel, not Caddy
+ enableCaddy = false; # beryllium ingress is managed by nginx in Omni/Dev/Vpn.nix
};
}
diff --git a/Omni/Dev/Beryllium/Ava.nix b/Omni/Dev/Beryllium/Ava.nix
index 0fe2b4cd..d370b8c8 100644
--- a/Omni/Dev/Beryllium/Ava.nix
+++ b/Omni/Dev/Beryllium/Ava.nix
@@ -51,9 +51,7 @@
}
];
- # Note: Tailscale Funnel for beryllium ingress is configured via:
- # tailscale funnel --bg 80
- # Caddy then proxies all requests to Omni.Web on 8079.
- # This persists in tailscaled config and doesn't need a systemd service.
- # URL: https://beryllium.oryx-ide.ts.net/
+ # Public ingress is now served by nginx virtual hosts in Omni/Dev/Vpn.nix.
+ # Ava traffic is proxied to Omni.Web on port 8079.
+ # URL: https://ava.bensima.com/
}
diff --git a/Omni/Dev/Vpn.nix b/Omni/Dev/Vpn.nix
index d064c1a2..353975a7 100644
--- a/Omni/Dev/Vpn.nix
+++ b/Omni/Dev/Vpn.nix
@@ -1,4 +1,4 @@
-{config, ...}:
+{config, lib, ...}:
/*
This module defines the VPN server using tailscale and a DNS-level filtering
service with AdGuard. It's fairly restrictive, but blocks lots of malicious and
@@ -6,31 +6,74 @@ inappropriate sites, as well as a ton of ads.
*/
let
ports = import ../Cloud/Ports.nix;
+ isBeryllium = config.networking.hostName == "beryllium";
in {
- services.headscale = {
- enable = false; # don't use headscale rn, just use tailscale.com
+ services.headscale = lib.mkIf isBeryllium {
+ enable = true;
address = "0.0.0.0";
port = ports.headscale;
- settings = {dns.base_domain = "bensima.com";};
+ settings = {
+ server_url = "https://hs.bensima.com";
+ dns = {
+ base_domain = "hs.bensima.com";
+ magic_dns = true;
+ nameservers.global = ["100.64.0.1"];
+ };
+ derp = {
+ server.enabled = false;
+ urls = ["https://controlplane.tailscale.com/derpmap/default"];
+ };
+ };
};
- environment.systemPackages = [config.services.headscale.package];
+ environment.systemPackages = lib.optionals isBeryllium [config.services.headscale.package];
services.tailscale = {
enable = true;
- extraUpFlags = [
- "--accept-dns=true"
- "--advertise-exit-node"
- ];
+ extraUpFlags =
+ [
+ "--login-server=https://hs.bensima.com"
+ "--accept-dns=true"
+ ]
+ ++ lib.optionals isBeryllium ["--advertise-exit-node"];
};
networking.firewall = {
checkReversePath = "loose";
trustedInterfaces = ["tailscale0"];
allowedUDPPorts = [config.services.tailscale.port];
+ allowedTCPPorts = lib.optionals isBeryllium [
+ ports.http
+ ports.https
+ ];
+ };
+
+ services.nginx = lib.mkIf isBeryllium {
+ enable = true;
+ recommendedProxySettings = true;
+ recommendedTlsSettings = true;
+ virtualHosts = {
+ "ava.bensima.com" = {
+ enableACME = true;
+ forceSSL = true;
+ locations."/" = {
+ proxyPass = "http://127.0.0.1:8079";
+ proxyWebsockets = true;
+ };
+ };
+
+ "hs.bensima.com" = {
+ enableACME = true;
+ forceSSL = true;
+ locations."/" = {
+ proxyPass = "http://127.0.0.1:${toString ports.headscale}";
+ proxyWebsockets = true;
+ };
+ };
+ };
};
- services.adguardhome = {
+ services.adguardhome = lib.mkIf isBeryllium {
enable = true;
openFirewall = true;
settings = {