jenkins 서버에서 원격 서버에 배포할 jar파일을 전달하려던 중, 많이 쓰이던 Publish over SSH 의 취약점이 발견되어 지원 종료되었다는 소식을 들었습니다. 이를 대체하기 위해 scp 명령어를 사용하여 script로 SSH접속을 시도하여보았습니다. script로 직접 작업을 작성해야하기 때문에 시간이 조금 더 걸리겠지만, original을 먼저 경험해보아야 plugin이나 docker와 같은 편리한 도구의 장점을 더 깨달을 수 있을 것이라 생각했습니다. 또한 빌드와 배포 과정을 좀 더 이해할 수 있을 것 같아 이 방법을 사용해보기로 하였습니다.
→ 공개/비밀키 사용
ssh-keygen -t rsa
생성시 모든 질문엔 enter
ssh-copy-id [user]@[hostname]
위에서 클라이언트가 보낸 과정을 통해 .ssh폴더에 authorized_keys가 생긴 것을 확인할 수 있습니다. 이 파일에 공개키가 저장되어있습니다.
# 제대로 들어왔는지 확인
cat authorized_keys
# 파일의 권한 수정
sudo chmod 600 ~/.ssh/authorized_keys
저는 해당 파일의 권한을 소유자만 읽기,쓰기가 가능하도록 설정하였습니다. 이 부분은 상황에 따라 다르게 적용하시면 될 것 같습니다.
# sshd 데몬 재시작
sudo service sshd restart
: 원격 서버의 파일을 전송하거나 가져오기 위해 사용하는 명령어
ssh 원격 접속 프로토콜을 기반으로 하며, ssh와 동일한 22번 포트를 이용하여 password, identity file을 이용해 안전하게 송수신 가능합니다.
scp -P 22 -i /var/lib/jenkins/.ssh/id_rsa.pem ./build/libs/mongo-log-0.0.1-SNAPSHOT.jar [user]@[ip주소]:/var/www/mongo-log/mongo-log-0.0.1-SNAPSHOT.jar
host key verification failed처음 원격 서버에 ssh로 접속할 때, RSA key fingerprint로 접속 여부를 물어봅니다.
연결하려는 원격 서버에 연결중인지 즉, 신뢰하는 호스트인지 확인하는 의도입니다.
yes를 입력하면 원격 서버를 기반으로 하는 fingerprint가 생성되어 클라이언트의 known-hosts에 저장이 됩니다. 따라서 설정 이후에 host에 접속할 수 있습니다.
~/.ssh 경로에서 cat known_hosts 로 확인을 해보면, ip주소와 공개키가 저장되어 있는것을 확인하실 수 있습니다. 그래서 만약에 해당 정보가 변경된다면 문제가 발생할 수 있어 known_hosts 파일을 수정해야하는 상황도 종종 발생하는 듯 합니다.
Pseudo-terminal will not be allocated because stdin is not a terminal.pseudo terminal은 터미널처럼 상호작용하여 소통합니다. pipe를 통해 원격으로 ssh를 실행하면 위와 같은 에러가 나올 수 있는데, 이는 터미널처럼 상호작용하지 않아 ssh에 대해 지정된 명령이 없기 때문입니다.
-T 옵션 사용 : pseudo terminal 할당을 하지 못하도록 설정
원하는 명령만 실행하고 exit하고 싶을 때 사용하면 됩니다.
# 1. -T 옵션 사용
# jenkins 서버에 있는 sh파일을 입력으로 재지정하여 sh파일 내부 명령어를 원격 서버에서 실행시킴
ssh -i /var/lib/jenkins/.ssh/id_rsa.pem [user]@[ip주소] -T sh < /var/lib/jenkins/restart_systemd.sh
bash 명령어 사용
-q 옵션 사용
단일 명령어 사용
# 4. 단일 명령어 사용
ssh -i /var/lib/jenkins/.ssh/id_rsa.pem [user]@[ip주소]"sudo systemctl restart mongo-log.service"
위의 방법 중에서 하나를 선택해 실행하였더니 아래와 같은 에러가 발생하였습니다.
# 결과
Failed to restart mongo-log.service: Interactive authentication required.
sudo권한의 명령어를 사용하려면 비밀번호를 입력해야하지만, 이 경우 pseudo terminal이 아니기 때문에 오류가 나는 것입니다.
배포할 원격 서버의 /etc/sudoers 설정파일을 수정하여 모든 명령, 또는 특정 명령에 대해 비밀번호를 요청하지 않도록 설정할 수 있습니다.
# 맨 아래에 추가
[sudo 계정 이름] ALL=NOPASSWD: /bin/systemctl restart mongo-log.service
위의 줄을 통해 sudo 권한을 가진 계정에서 sudo systemctl restart mongo-log.service 명령이 입력되어도 비밀번호를 요청하지 않아 원격 서버에서 systemd가 재시작하는 것을 확인할 수 있었습니다.

이번 경험으로 서버에 배포를 하기 위한 script가 어떤식으로 구성되는지 확인해볼 수 있어 배포의 흐름을 쉽게 이해할 수 있었습니다. 또한 많이 봐왔던 ssh-keygen 명령어를 사용한 키 생성에 익숙해질 수 있어 좋았습니다. 이후에는 docker나 다양한 툴을 사용해보면서 장단점을 비교해 볼 생각입니다.