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나 다양한 툴을 사용해보면서 장단점을 비교해 볼 생각입니다.