Add an opt-in insecure-TLS mode for the agent, for self-signed certs

Installing the agent against a Homelab Manager instance with a
self-signed cert failed: curl verifies TLS by default on the install
download, the report-tasks.sh fetch inside install.sh, and every
periodic check-in — not just the outer one-liner, so passing -k to only
that first curl wasn't enough. Mirrors the existing Proxmox/Synology
"insecure" toggle pattern already in this app.

- install.sh and report-tasks.sh accept API_INSECURE=true, adding -k to
  their own curl calls; install.sh persists it into the agent's env
  file so the periodic systemd timer picks it up too.
- The Servers & Tasks page has a new checkbox next to the generated
  install/uninstall commands that adds -k and API_INSECURE=true for
  you, so the outer one-liner (which install.sh's own logic can't
  touch) also skips verification.

Off by default — only for a trusted LAN.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
bobbanandClaude Sonnet 5 committed 2026-09-15 18:26:19 +02:00
1 parent f5d3c25c89
commit 130212baec
3 files changed
+56 -11

No files matched your search

+25 -8
View File
@@ -22,12 +22,17 @@ const SCHEDULE_TYPE_OPTIONS: { value: ScheduleType; label: string }[] = [
{ value: "manual", label: "Other / manual" },
];
function installCommand(token: string): string {
return `curl -fsSL ${window.location.origin}/agent/linux/install.sh | sudo API_URL=${window.location.origin} API_TOKEN=${token} bash`;
function installCommand(token: string, insecure: boolean): string {
const curlFlags = insecure ? "-fsSL -k" : "-fsSL";
const envVars = insecure
? `API_URL=${window.location.origin} API_TOKEN=${token} API_INSECURE=true`
: `API_URL=${window.location.origin} API_TOKEN=${token}`;
return `curl ${curlFlags} ${window.location.origin}/agent/linux/install.sh | sudo ${envVars} bash`;
}
function uninstallCommand(): string {
return `curl -fsSL ${window.location.origin}/agent/linux/uninstall.sh | sudo bash`;
function uninstallCommand(insecure: boolean): string {
const curlFlags = insecure ? "-fsSL -k" : "-fsSL";
return `curl ${curlFlags} ${window.location.origin}/agent/linux/uninstall.sh | sudo bash`;
}
const emptyTaskForm = {
@@ -64,6 +69,7 @@ export default function ServersTasks({ user }: { user: CurrentUser }) {
const [serverDescription, setServerDescription] = useState("");
const [newToken, setNewToken] = useState<{ server: ServerRecord; token: string } | null>(null);
const [uninstallFor, setUninstallFor] = useState<ServerRecord | null>(null);
const [insecureAgent, setInsecureAgent] = useState(false);
const loadServers = useCallback(() => {
return api.servers
@@ -266,12 +272,23 @@ export default function ServersTasks({ user }: { user: CurrentUser }) {
<code className="form-control">{newToken.token}</code>
<CopyButton text={newToken.token} />
</div>
<label className="form-check mb-2">
<input
type="checkbox"
className="form-check-input"
checked={insecureAgent}
onChange={(e) => setInsecureAgent(e.target.checked)}
/>
<span className="form-check-label">
This Homelab Manager instance uses a self-signed certificate (skip TLS verification on the agent)
</span>
</label>
<p className="text-secondary">
Install the agent on the server (run as root — put sudo right after the pipe, not before curl):
</p>
<div className="input-group">
<pre className="form-control text-wrap mb-0">{installCommand(newToken.token)}</pre>
<CopyButton text={installCommand(newToken.token)} />
<pre className="form-control text-wrap mb-0">{installCommand(newToken.token, insecureAgent)}</pre>
<CopyButton text={installCommand(newToken.token, insecureAgent)} />
</div>
</div>
<div className="card-footer">
@@ -290,8 +307,8 @@ export default function ServersTasks({ user }: { user: CurrentUser }) {
<div className="card-body">
<p className="text-secondary">Run this on the server as root to stop and remove the agent (its entry here is kept):</p>
<div className="input-group">
<pre className="form-control text-wrap mb-0">{uninstallCommand()}</pre>
<CopyButton text={uninstallCommand()} />
<pre className="form-control text-wrap mb-0">{uninstallCommand(insecureAgent)}</pre>
<CopyButton text={uninstallCommand(insecureAgent)} />
</div>
</div>
<div className="card-footer">