如題
場景是用 AWS Lambda 做個 DC 機器人在發送指令後去連線 EC2 執行指令
AWS Lambda 使用 Nodejs 撰寫,用 simple-ssh 套件連線 EC2 執行指令會卡住並超時,不太清楚 Lambda 是否對 ssh 連線有什麼限制。
其中 simple-ssh 連線這段在本地端測試是可以連上去 EC2 並執行指令的。
以下附上 Lambda 程式碼
const fs = require('fs');
const SSH = require('simple-ssh');
const nacl = require('tweetnacl');
const {
InteractionType,
InteractionResponseType,
InteractionResponseFlags,
MessageComponentTypes,
ButtonStyleTypes,
} = require('discord-interactions');
const pemfile = 'xxx.pem';
const user = 'server1';
const host = 'xx.xxx.xx.xxx';
const password = 'xxxx';
exports.handler = async (event) => {
try {
console.log(event);
// Checking signature (requirement 1.)
// Your public key can be found on your application in the Developer Portal
const PUBLIC_KEY = process.env.PUBLIC_KEY;
const signature = event.headers['x-signature-ed25519'];
const timestamp = event.headers['x-signature-timestamp'];
const strBody = event.body; // should be string, for successful sign
const isVerified = nacl.sign.detached.verify(
Buffer.from(timestamp + strBody),
Buffer.from(signature, 'hex'),
Buffer.from(PUBLIC_KEY, 'hex')
);
console.log(isVerified);
if (!isVerified) {
return {
statusCode: 401,
body: JSON.stringify('invalid request signature'),
};
}
const body = JSON.parse(strBody);
// Replying to ping (requirement 2.)
if (body.type == InteractionType.PING) {
return {
statusCode: 200,
body: JSON.stringify({ type: InteractionResponseType.PONG }),
};
}
// Handle Command
if (body.type === InteractionType.APPLICATION_COMMAND) {
if (body.data.name === '查看') {
const ssh = new SSH({
host: host,
user: user,
password: password,
key: fs.readFileSync(pemfile)
});
const prom = new Promise((resolve, reject) => {
let ourout = "";
ssh
.exec('myserver status', {
exit: () => {
ourout += "\nSuccessfully Exited!";
resolve(ourout);
},
out: (stdout) => {
ourout += stdout;
}
})
.start({
fail: (e) => {
console.log(e);
reject(e);
}
});
});
console.log('wait ssh');
const res = await prom;
console.log('complete ssh');
return JSON.stringify({
type: InteractionResponseType.CHANNEL_MESSAGE_WITH_SOURCE,
data: { content: res },
});
}
}
} catch (error) {
console.log(error);
return {
statusCode: 404
};
}
};