Skip to main content

node-ssh로 SSH 연결하기

시작하기에 앞서

주의

해당 블로그의 모든 문서는 학습한 내용을 제 방식으로 정리하여 작성하고 있습니다.
순수 창작물도 아니고, 틀린 내용이 있을 수 있으므로 참고하고 읽어주시면 감사하겠습니다.

개요

이번에 NodeJS/Express 프로젝트에서 AWS EC2 Ubuntu 인스턴스에 SSH로 접속해서, 명령어를 실행하고 결과를 받아볼 필요성이 생겼었습니다.

NodeJS 서버에서 특정 이미지들이 저장되어 있는 EC2 인스턴스에서 가장 최근에 저장된 이미지의 파일명을 알아내야 했습니다.

(NodeJS 서버와 이미지가 저장된 인스턴스는 운영체제가 분리되어 있는 상황)

이미지가 저장되어 있는 인스턴스에도 NodeJS나 Flask와 같은 프레임워크들로 API 서버를 하나 구축해 보면 어떨까도 생각해 봤지만,

이미지의 파일명 하나를 응답받기 위해서 별도의 API 서버를 구축한다는 게 별로 마음에 들지도 않았고, 더 괜찮은 방법이 있을 것 같았습니다.

그래서 열심히 찾아보다가, node-ssh라는 패키지를 알게 되었고, 이걸 어떻게 잘 사용해 보면 SSH로 이미지가 저장된 인스턴스에 연결해서 명령어를 실행하고, 결과를 받으면 쉽게 해결되지 않을까 하는 마음에 접근해 봤고, 사용법 정도를 간단하게 정리해 볼까 합니다.

node-ssh 설치하기

npm install node-ssh

해당 명령어를 통해서 node-ssh를 설치해 줍니다.

SSH 연결 작업

const { NodeSSH } = require('node-ssh');
const ssh = new NodeSSH();
require('dotenv').config(); // .env를 사용하기 위함

ssh.connect({
host: process.env.SSH_HOST,
username: process.env.SSH_USERNAME,
privateKeyPath: process.env.SSH_PRIVATE_KEY_PATH,
})
.then(() => { // Promise<NodeSSH>
return ssh.execCommand('ls -all', { cwd: '/home' });
})
.then((response) => { // SSHExecCommandResponse
console.log(`stdout = ${response.stdout}`);
console.log(`stderr = ${response.stderr}`);
});

먼저 require()를 통해서 NodeSSH를 import 해주고, new NodeSSH()로 ssh 변수에 객체의 인스턴스를 생성해 줍니다. 그 후에 ssh.connect() 함수의 매개변수(givenConfig)에 연결할 서버의 host, username, privateKeyPath를 설정해 주면 됩니다.

기존에 ssh -i AWS_EC2_KEY_PAIR ubuntu@127.0.0.1 이런 식으로 인스턴스에 접속했었다면, ubuntu는 username 부분에 적어주면 되고, 아이피 주소에 해당하는 127.0.0.1은 host 부분에 적어주면 됩니다.

마지막으로 privateKeyPath는 AWS 생성 시 발급받은 키 페어(*.ppk) 파일의 경로를 적어주면 됩니다. 저 같은 경우는 확장자까지 정확하게 적어주어야 정상적으로 동작했습니다. *.pem은 안 해봐서 동작하는지 잘 모르겠습니다.


return ssh.execCommand('ls -all', { cwd: '/home' });

execCommand()함수를 통해서 원격으로 접속한 인스턴스에서 명령어를 실행해 볼 수 있습니다. 매개변수는 순서대로 givenCommand, options를 넘겨주면 됩니다. 첫 번째 매개변수인 givenCommand 부분에 리눅스 명령어를 문자열로 적어주면 되고, 두 번째 매개변수에 해당하는 옵션은 객체로 넘겨주면 됩니다.

cwd는 current working directory로 현재 작업 디렉터리를 options에 명시해 줬습니다.

간단한 예시이므로 명령어로 여기서는 간단하게 ls를 택했습니다. 상황에 맞게 명령어를 설정하여 사용하시면 될 것 같습니다.


console.log(`stdout = ${response.stdout}`);

마지막으로 response.stdout을 통해서 명령어의 실행 결과를 확인해 볼 수 있습니다.


response.stdout
stdout = total 16
drwxr-xr-x 4 root root 4096 Nov 17 07:33 .
drwxr-xr-x 23 root root 4096 Nov 17 06:27 ..
drwxr-xr-x 7 root root 4096 Nov 3 13:02 directory1
drwxr-xr-x 5 ubuntu ubuntu 4096 Nov 17 07:29 directory2

참고 자료

npm node-ssh Readme
How to SSH using Node.js
Node.js node-ssh 클라이언트