mirror of
https://github.com/DeNNiiInc/dbgate.git
synced 2026-04-25 09:45:59 +00:00
ssh tunnel WIP
This commit is contained in:
@@ -166,7 +166,9 @@ function start() {
|
|||||||
if (time - lastPing > 40 * 1000) {
|
if (time - lastPing > 40 * 1000) {
|
||||||
logger.info('Server connection not alive, exiting');
|
logger.info('Server connection not alive, exiting');
|
||||||
const driver = requireEngineDriver(storedConnection);
|
const driver = requireEngineDriver(storedConnection);
|
||||||
await driver.close(dbhan);
|
if (dbhan) {
|
||||||
|
await driver.close(dbhan);
|
||||||
|
}
|
||||||
process.exit(0);
|
process.exit(0);
|
||||||
}
|
}
|
||||||
}, 10 * 1000);
|
}, 10 * 1000);
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ const { getLogger, extractErrorLogData, extractErrorMessage } = require('dbgate-
|
|||||||
|
|
||||||
const logger = getLogger('sshProcess');
|
const logger = getLogger('sshProcess');
|
||||||
|
|
||||||
async function getSshConnection(connection) {
|
async function getSshConnection(connection, tunnelConfig) {
|
||||||
const sshConfig = {
|
const sshConfig = {
|
||||||
endHost: connection.sshHost || '',
|
endHost: connection.sshHost || '',
|
||||||
endPort: connection.sshPort || 22,
|
endPort: connection.sshPort || 22,
|
||||||
@@ -23,6 +23,7 @@ async function getSshConnection(connection) {
|
|||||||
: undefined,
|
: undefined,
|
||||||
skipAutoPrivateKey: true,
|
skipAutoPrivateKey: true,
|
||||||
noReadline: true,
|
noReadline: true,
|
||||||
|
bindHost: tunnelConfig.fromHost,
|
||||||
};
|
};
|
||||||
|
|
||||||
const sshConn = new SSHConnection(sshConfig);
|
const sshConn = new SSHConnection(sshConfig);
|
||||||
@@ -31,7 +32,7 @@ async function getSshConnection(connection) {
|
|||||||
|
|
||||||
async function handleStart({ connection, tunnelConfig }) {
|
async function handleStart({ connection, tunnelConfig }) {
|
||||||
try {
|
try {
|
||||||
const sshConn = await getSshConnection(connection);
|
const sshConn = await getSshConnection(connection, tunnelConfig);
|
||||||
await sshConn.forward(tunnelConfig);
|
await sshConn.forward(tunnelConfig);
|
||||||
|
|
||||||
process.send({
|
process.send({
|
||||||
|
|||||||
@@ -130,7 +130,7 @@ class SSHConnection {
|
|||||||
const connectionToBastion = await this.connect(bastionHost);
|
const connectionToBastion = await this.connect(bastionHost);
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
connectionToBastion.forwardOut(
|
connectionToBastion.forwardOut(
|
||||||
'127.0.0.1',
|
this.options.bindHost,
|
||||||
22,
|
22,
|
||||||
this.options.endHost,
|
this.options.endHost,
|
||||||
this.options.endPort || 22,
|
this.options.endPort || 22,
|
||||||
@@ -228,9 +228,9 @@ class SSHConnection {
|
|||||||
options.toPort
|
options.toPort
|
||||||
);
|
);
|
||||||
connection.forwardOut(
|
connection.forwardOut(
|
||||||
'127.0.0.1',
|
this.options.bindHost,
|
||||||
options.fromPort,
|
options.fromPort,
|
||||||
options.toHost || '127.0.0.1',
|
options.toHost || this.options.bindHost,
|
||||||
options.toPort,
|
options.toPort,
|
||||||
(error, stream) => {
|
(error, stream) => {
|
||||||
if (error) {
|
if (error) {
|
||||||
@@ -241,7 +241,7 @@ class SSHConnection {
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
})
|
})
|
||||||
.listen(options.fromPort, '127.0.0.1', () => {
|
.listen(options.fromPort, this.options.bindHost, () => {
|
||||||
return resolve();
|
return resolve();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -63,7 +63,7 @@ async function connectUtility(driver, storedConnection, connectionMode, addition
|
|||||||
throw new Error(tunnel.message);
|
throw new Error(tunnel.message);
|
||||||
}
|
}
|
||||||
|
|
||||||
connection.server = 'localhost';
|
connection.server = tunnel.localHost;
|
||||||
connection.port = tunnel.localPort;
|
connection.port = tunnel.localPort;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -61,15 +61,20 @@ function callForwardProcess(connection, tunnelConfig, tunnelCacheKey) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async function getSshTunnel(connection) {
|
async function getSshTunnel(connection) {
|
||||||
|
const config = require('../controllers/config');
|
||||||
|
|
||||||
const tunnelCacheKey = stableStringify(_.pick(connection, TUNNEL_FIELDS));
|
const tunnelCacheKey = stableStringify(_.pick(connection, TUNNEL_FIELDS));
|
||||||
|
const globalSettings = await config.getSettings();
|
||||||
|
|
||||||
return await lock.acquire(tunnelCacheKey, async () => {
|
return await lock.acquire(tunnelCacheKey, async () => {
|
||||||
if (sshTunnelCache[tunnelCacheKey]) return sshTunnelCache[tunnelCacheKey];
|
if (sshTunnelCache[tunnelCacheKey]) return sshTunnelCache[tunnelCacheKey];
|
||||||
const localPort = await portfinder.getPortPromise({ port: 10000, stopPort: 60000 });
|
const localPort = await portfinder.getPortPromise({ port: 10000, stopPort: 60000 });
|
||||||
|
const localHost = globalSettings?.['connection.sshBindHost'] || '127.0.0.1';
|
||||||
// workaround for `getPortPromise` not releasing the port quickly enough
|
// workaround for `getPortPromise` not releasing the port quickly enough
|
||||||
await new Promise(resolve => setTimeout(resolve, 500));
|
await new Promise(resolve => setTimeout(resolve, 500));
|
||||||
const tunnelConfig = {
|
const tunnelConfig = {
|
||||||
fromPort: localPort,
|
fromPort: localPort,
|
||||||
|
fromHost: localHost,
|
||||||
toPort: connection.port,
|
toPort: connection.port,
|
||||||
toHost: connection.server,
|
toHost: connection.server,
|
||||||
};
|
};
|
||||||
@@ -87,6 +92,7 @@ async function getSshTunnel(connection) {
|
|||||||
sshTunnelCache[tunnelCacheKey] = {
|
sshTunnelCache[tunnelCacheKey] = {
|
||||||
state: 'ok',
|
state: 'ok',
|
||||||
localPort,
|
localPort,
|
||||||
|
localHost,
|
||||||
subprocess,
|
subprocess,
|
||||||
};
|
};
|
||||||
return sshTunnelCache[tunnelCacheKey];
|
return sshTunnelCache[tunnelCacheKey];
|
||||||
|
|||||||
@@ -202,6 +202,18 @@ ORDER BY
|
|||||||
defaultValue="30"
|
defaultValue="30"
|
||||||
disabled={values['connection.autoRefresh'] === false}
|
disabled={values['connection.autoRefresh'] === false}
|
||||||
/>
|
/>
|
||||||
|
<FormSelectField
|
||||||
|
label="Local host address for SSH connections"
|
||||||
|
name="connection.sshBindHost"
|
||||||
|
isNative
|
||||||
|
defaultValue="127.0.0.1"
|
||||||
|
options={[
|
||||||
|
{ value: '127.0.0.1', label: '127.0.0.1 (IPv4)' },
|
||||||
|
{ value: '::1', label: '::1 (IPv6)' },
|
||||||
|
{ value: 'localhost', label: 'localhost (domain name)' },
|
||||||
|
{ value: 'testerror', label: 'testerror' },
|
||||||
|
]}
|
||||||
|
/>
|
||||||
|
|
||||||
<div class="heading">Query sessions</div>
|
<div class="heading">Query sessions</div>
|
||||||
<FormCheckboxField
|
<FormCheckboxField
|
||||||
|
|||||||
Reference in New Issue
Block a user