概要
ioredisとssh2モジュールを使用して、SSH経由でRedisへ接続します。
環境
- Node.js v8.15.0
- ioredis v4.2.0
- ssh2 v0.8.2
方法
依存モジュールを読み込みます。
const Redis = require('ioredis');
const { Client: SSHClient } = require('ssh2');
const net = require('net');
const fs = require('fs');
SSHサーバへ接続する関数を用意します。
function connectToSSH(options) {
return new Promise((resolve, reject) => {
const connection = new SSHClient();
connection.once('ready', () => resolve(connection));
connection.once('error', reject);
connection.connect(options);
});
}
Redisへ接続するためのヘルパー関数を用意します。
function connectToRedis(options) {
const redis = new Redis(options);
return new Promise((resolve, reject) => {
redis.once('error', reject);
redis.once('ready', () => resolve(redis));
});
}
ポートフォワーディング用の中間サーバを作成します。
server.listen
の第1引数に0
を渡すと、システムの空きポートが割り当てられます。
function createIntermediateServer(connectionListener) {
return new Promise((resolve, reject) => {
const server = net.createServer(connectionListener);
server.once('error', reject);
server.listen(0, () => resolve(server));
});
}
一連のヘルパー関数をまとめて、SSH経由でRedisへ接続する関数を用意します。
async function connectToRedisViaSSH(options = {
ssh: {
host: 'localhost',
port: 22
},
redis: {
host: 'localhost',
port: 6379
}
}) {
const sshConnection = await connectToSSH({
host: options.ssh.host,
port: options.ssh.port,
username: options.ssh.username,
privateKey: options.ssh.privateKey,
passphrase: options.ssh.passphrase
});
const server = await createIntermediateServer(socket => {
sshConnection.forwardOut(
socket.remoteAddress,
socket.remotePort,
options.redis.host,
options.redis.port,
(error, stream) => {
if (error) {
socket.end();
} else {
socket.pipe(stream).pipe(socket);
}
}
);
});
// Redisサーバのアドレスではなく、中間サーバのアドレスを指定します。
const redis = await connectToRedis({
host: server.address().address,
port: server.address().port
});
return redis;
}
作成した関数を利用してRedisへ接続します。
const redis = await connectToRedisViaSSH({
ssh: {
host: '<ssh-server-address>',
port: 22,
username: '<username>',
privateKey: fs.readFileSync('/path/to/private-key'),
passphrase: '<passphrase>'
},
redis: {
host: '<redis-server-address>',
port: 6379
}
});
const keys = await redis.keys('*');
console.log(keys);
参考