mirror of
https://github.com/Termix-SSH/Termix.git
synced 2026-07-15 04:43:36 +00:00
Support Vault auth for monitors (#1004)
This commit is contained in:
@@ -104,6 +104,7 @@ interface SSHHostWithCredentials {
|
|||||||
rdpPort?: number;
|
rdpPort?: number;
|
||||||
vncPort?: number;
|
vncPort?: number;
|
||||||
telnetPort?: number;
|
telnetPort?: number;
|
||||||
|
vaultProfile?: { id?: number | null } | null;
|
||||||
}
|
}
|
||||||
|
|
||||||
type StatusEntry = {
|
type StatusEntry = {
|
||||||
@@ -1128,6 +1129,8 @@ async function buildSshConfig(
|
|||||||
// no credentials needed
|
// no credentials needed
|
||||||
} else if (host.authType === "opkssh") {
|
} else if (host.authType === "opkssh") {
|
||||||
// cert auth setup happens in createSshFactory (needs client instance)
|
// cert auth setup happens in createSshFactory (needs client instance)
|
||||||
|
} else if (host.authType === "vault") {
|
||||||
|
// cert auth setup happens in createSshFactory (needs client instance)
|
||||||
} else if (host.authType === "credential") {
|
} else if (host.authType === "credential") {
|
||||||
if (host.password) {
|
if (host.password) {
|
||||||
base.password = host.password;
|
base.password = host.password;
|
||||||
@@ -1186,6 +1189,10 @@ function createSshFactory(host: SSHHostWithCredentials): () => Promise<Client> {
|
|||||||
}
|
}
|
||||||
const { setupOPKSSHCertAuth } = await import("./opkssh-cert-auth.js");
|
const { setupOPKSSHCertAuth } = await import("./opkssh-cert-auth.js");
|
||||||
await setupOPKSSHCertAuth(config, client, token, host.username);
|
await setupOPKSSHCertAuth(config, client, token, host.username);
|
||||||
|
} else if (host.authType === "vault") {
|
||||||
|
const { setupVaultSshSignerAuth } =
|
||||||
|
await import("./vault-ssh-connect.js");
|
||||||
|
await setupVaultSshSignerAuth(config, client, host);
|
||||||
}
|
}
|
||||||
|
|
||||||
const proxyConfig: SOCKS5Config | null =
|
const proxyConfig: SOCKS5Config | null =
|
||||||
@@ -2070,6 +2077,10 @@ app.post("/metrics/start/:id", validateHostId, async (req, res) => {
|
|||||||
}
|
}
|
||||||
const { setupOPKSSHCertAuth } = await import("./opkssh-cert-auth.js");
|
const { setupOPKSSHCertAuth } = await import("./opkssh-cert-auth.js");
|
||||||
await setupOPKSSHCertAuth(config, client, token, host.username);
|
await setupOPKSSHCertAuth(config, client, token, host.username);
|
||||||
|
} else if (host.authType === "vault") {
|
||||||
|
const { setupVaultSshSignerAuth } =
|
||||||
|
await import("./vault-ssh-connect.js");
|
||||||
|
await setupVaultSshSignerAuth(config, client, host);
|
||||||
}
|
}
|
||||||
|
|
||||||
const connectionPromise = new Promise<{
|
const connectionPromise = new Promise<{
|
||||||
|
|||||||
@@ -95,6 +95,8 @@ async function buildSshConfig(host: SSHHost): Promise<ConnectConfig> {
|
|||||||
}
|
}
|
||||||
} else if (host.authType === "none") {
|
} else if (host.authType === "none") {
|
||||||
// no credentials needed
|
// no credentials needed
|
||||||
|
} else if (host.authType === "vault") {
|
||||||
|
// cert auth setup happens in connectToHost (needs client instance)
|
||||||
} else if (host.authType === "agent") {
|
} else if (host.authType === "agent") {
|
||||||
const result = await applyAgentAuth(
|
const result = await applyAgentAuth(
|
||||||
base as Record<string, unknown>,
|
base as Record<string, unknown>,
|
||||||
@@ -118,6 +120,12 @@ export function connectToHost(host: SSHHost): () => Promise<Client> {
|
|||||||
const config = await buildSshConfig(host);
|
const config = await buildSshConfig(host);
|
||||||
const client = new Client();
|
const client = new Client();
|
||||||
|
|
||||||
|
if (host.authType === "vault") {
|
||||||
|
const { setupVaultSshSignerAuth } =
|
||||||
|
await import("./vault-ssh-connect.js");
|
||||||
|
await setupVaultSshSignerAuth(config, client, host);
|
||||||
|
}
|
||||||
|
|
||||||
const proxyConfig: SOCKS5Config | null =
|
const proxyConfig: SOCKS5Config | null =
|
||||||
host.useSocks5 &&
|
host.useSocks5 &&
|
||||||
(host.socks5Host ||
|
(host.socks5Host ||
|
||||||
|
|||||||
@@ -0,0 +1,39 @@
|
|||||||
|
import type { Client, ConnectConfig } from "ssh2";
|
||||||
|
|
||||||
|
type VaultAuthHost = {
|
||||||
|
id: number;
|
||||||
|
username: string;
|
||||||
|
userId?: string | null;
|
||||||
|
vaultProfile?: { id?: number | null } | null;
|
||||||
|
};
|
||||||
|
|
||||||
|
export async function setupVaultSshSignerAuth(
|
||||||
|
config: ConnectConfig,
|
||||||
|
client: Client,
|
||||||
|
host: VaultAuthHost,
|
||||||
|
): Promise<void> {
|
||||||
|
if (!host.userId) {
|
||||||
|
throw new Error("Vault SSH signer authentication requires a user session");
|
||||||
|
}
|
||||||
|
|
||||||
|
const vaultProfileId = host.vaultProfile?.id;
|
||||||
|
if (!vaultProfileId) {
|
||||||
|
throw new Error("Host has no Vault signer profile configured");
|
||||||
|
}
|
||||||
|
|
||||||
|
const { getVaultCert } = await import("./vault-signer-auth.js");
|
||||||
|
const cert = await getVaultCert(host.userId, vaultProfileId);
|
||||||
|
if (!cert) {
|
||||||
|
throw new Error(
|
||||||
|
"Vault SSH signer authentication required. Please open a Terminal connection first.",
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const { setupOPKSSHCertAuth } = await import("./opkssh-cert-auth.js");
|
||||||
|
await setupOPKSSHCertAuth(
|
||||||
|
config,
|
||||||
|
client,
|
||||||
|
{ privateKey: cert.privateKey, sshCert: cert.sshCert },
|
||||||
|
host.username,
|
||||||
|
);
|
||||||
|
}
|
||||||
+4
-1
@@ -109,7 +109,8 @@ export interface Host {
|
|||||||
| "none"
|
| "none"
|
||||||
| "opkssh"
|
| "opkssh"
|
||||||
| "tailscale"
|
| "tailscale"
|
||||||
| "agent";
|
| "agent"
|
||||||
|
| "vault";
|
||||||
useWarpgate?: boolean;
|
useWarpgate?: boolean;
|
||||||
password?: string;
|
password?: string;
|
||||||
key?: string;
|
key?: string;
|
||||||
@@ -123,6 +124,8 @@ export interface Host {
|
|||||||
autostartKeyPassword?: string;
|
autostartKeyPassword?: string;
|
||||||
|
|
||||||
credentialId?: number;
|
credentialId?: number;
|
||||||
|
vaultProfileId?: number | null;
|
||||||
|
vaultProfile?: { id?: number | null };
|
||||||
overrideCredentialUsername?: boolean;
|
overrideCredentialUsername?: boolean;
|
||||||
userId?: string;
|
userId?: string;
|
||||||
enableTerminal: boolean;
|
enableTerminal: boolean;
|
||||||
|
|||||||
Reference in New Issue
Block a user