fix(terminal): preserve PATH for SSH proxy commands (#11638)
This commit is contained in:
parent
2a25e0490e
commit
bf874029d8
6 changed files with 40 additions and 4 deletions
|
|
@ -4,7 +4,7 @@
|
||||||
'coolify' => [
|
'coolify' => [
|
||||||
'version' => env('COOLIFY_VERSION') ?: '4.3.18',
|
'version' => env('COOLIFY_VERSION') ?: '4.3.18',
|
||||||
'helper_version' => '1.0.16',
|
'helper_version' => '1.0.16',
|
||||||
'realtime_version' => '1.0.18',
|
'realtime_version' => '1.0.19',
|
||||||
'railpack_version' => '0.23.0',
|
'railpack_version' => '0.23.0',
|
||||||
'self_hosted' => env('SELF_HOSTED', true),
|
'self_hosted' => env('SELF_HOSTED', true),
|
||||||
'autoupdate' => env('AUTOUPDATE'),
|
'autoupdate' => env('AUTOUPDATE'),
|
||||||
|
|
|
||||||
|
|
@ -62,7 +62,7 @@ services:
|
||||||
retries: 10
|
retries: 10
|
||||||
timeout: 2s
|
timeout: 2s
|
||||||
soketi:
|
soketi:
|
||||||
image: '${REGISTRY_URL:-docker.io}/coollabsio/coolify-realtime:1.0.18'
|
image: '${REGISTRY_URL:-docker.io}/coollabsio/coolify-realtime:1.0.19'
|
||||||
ports:
|
ports:
|
||||||
- "${SOKETI_PORT:-6001}:6001"
|
- "${SOKETI_PORT:-6001}:6001"
|
||||||
- "6002:6002"
|
- "6002:6002"
|
||||||
|
|
|
||||||
|
|
@ -97,7 +97,7 @@ services:
|
||||||
retries: 10
|
retries: 10
|
||||||
timeout: 2s
|
timeout: 2s
|
||||||
soketi:
|
soketi:
|
||||||
image: 'ghcr.io/coollabsio/coolify-realtime:1.0.18'
|
image: 'ghcr.io/coollabsio/coolify-realtime:1.0.19'
|
||||||
pull_policy: always
|
pull_policy: always
|
||||||
container_name: coolify-realtime
|
container_name: coolify-realtime
|
||||||
restart: always
|
restart: always
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,7 @@ import {
|
||||||
extractSshArgs,
|
extractSshArgs,
|
||||||
extractTargetHost,
|
extractTargetHost,
|
||||||
extractTimeout,
|
extractTimeout,
|
||||||
|
getTerminalProcessEnv,
|
||||||
getTerminalSessionTimeout,
|
getTerminalSessionTimeout,
|
||||||
isAuthorizedTargetHost,
|
isAuthorizedTargetHost,
|
||||||
sanitizeSshArgs,
|
sanitizeSshArgs,
|
||||||
|
|
@ -401,7 +402,7 @@ async function handleCommand(ws, command, userId) {
|
||||||
cols: 80,
|
cols: 80,
|
||||||
rows: 30,
|
rows: 30,
|
||||||
cwd: process.env.HOME,
|
cwd: process.env.HOME,
|
||||||
env: {},
|
env: getTerminalProcessEnv(),
|
||||||
};
|
};
|
||||||
|
|
||||||
// NOTE: - Initiates a process within the Terminal container
|
// NOTE: - Initiates a process within the Terminal container
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,13 @@
|
||||||
export const MAX_TERMINAL_SESSION_TIMEOUT_SECONDS = 8 * 60 * 60;
|
export const MAX_TERMINAL_SESSION_TIMEOUT_SECONDS = 8 * 60 * 60;
|
||||||
|
|
||||||
|
const DEFAULT_TERMINAL_PATH = '/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin';
|
||||||
|
|
||||||
|
export function getTerminalProcessEnv(environment = process.env) {
|
||||||
|
return {
|
||||||
|
PATH: environment.PATH || DEFAULT_TERMINAL_PATH,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
export function getTerminalSessionTimeout() {
|
export function getTerminalSessionTimeout() {
|
||||||
return MAX_TERMINAL_SESSION_TIMEOUT_SECONDS;
|
return MAX_TERMINAL_SESSION_TIMEOUT_SECONDS;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@ import {
|
||||||
MAX_TERMINAL_SESSION_TIMEOUT_SECONDS,
|
MAX_TERMINAL_SESSION_TIMEOUT_SECONDS,
|
||||||
extractSshArgs,
|
extractSshArgs,
|
||||||
extractTargetHost,
|
extractTargetHost,
|
||||||
|
getTerminalProcessEnv,
|
||||||
getTerminalSessionTimeout,
|
getTerminalSessionTimeout,
|
||||||
isAuthorizedTargetHost,
|
isAuthorizedTargetHost,
|
||||||
normalizeHostForAuthorization,
|
normalizeHostForAuthorization,
|
||||||
|
|
@ -11,6 +12,32 @@ import {
|
||||||
validateSshArgs,
|
validateSshArgs,
|
||||||
} from './terminal-utils.js';
|
} from './terminal-utils.js';
|
||||||
|
|
||||||
|
test('getTerminalProcessEnv preserves the PATH needed by SSH proxy commands', () => {
|
||||||
|
assert.deepEqual(getTerminalProcessEnv({
|
||||||
|
PATH: '/usr/local/bin:/usr/bin:/bin',
|
||||||
|
APP_KEY: 'must-not-be-inherited',
|
||||||
|
}), {
|
||||||
|
PATH: '/usr/local/bin:/usr/bin:/bin',
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
test('getTerminalProcessEnv uses the default PATH when PATH is absent', () => {
|
||||||
|
assert.deepEqual(getTerminalProcessEnv({
|
||||||
|
APP_KEY: 'must-not-be-inherited',
|
||||||
|
}), {
|
||||||
|
PATH: '/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin',
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
test('getTerminalProcessEnv uses the default PATH when PATH is empty', () => {
|
||||||
|
assert.deepEqual(getTerminalProcessEnv({
|
||||||
|
PATH: '',
|
||||||
|
APP_KEY: 'must-not-be-inherited',
|
||||||
|
}), {
|
||||||
|
PATH: '/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin',
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
test('extractTargetHost normalizes quoted IPv4 hosts from generated ssh commands', () => {
|
test('extractTargetHost normalizes quoted IPv4 hosts from generated ssh commands', () => {
|
||||||
const sshArgs = extractSshArgs(
|
const sshArgs = extractSshArgs(
|
||||||
"timeout 3600 ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -o LogLevel=ERROR -o ServerAliveInterval=20 -o ConnectTimeout=10 'root'@'10.0.0.5' 'bash -se' << \\\\$abc\necho hi\nabc"
|
"timeout 3600 ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -o LogLevel=ERROR -o ServerAliveInterval=20 -o ConnectTimeout=10 'root'@'10.0.0.5' 'bash -se' << \\\\$abc\necho hi\nabc"
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue