scp 사용하여 원격 서버에 배포하기

sieun·2022년 8월 6일
0
post-thumbnail

개요

jenkins 서버에서 원격 서버에 배포할 jar파일을 전달하려던 중, 많이 쓰이던 Publish over SSH 의 취약점이 발견되어 지원 종료되었다는 소식을 들었습니다. 이를 대체하기 위해 scp 명령어를 사용하여 script로 SSH접속을 시도하여보았습니다. script로 직접 작업을 작성해야하기 때문에 시간이 조금 더 걸리겠지만, original을 먼저 경험해보아야 plugin이나 docker와 같은 편리한 도구의 장점을 더 깨달을 수 있을 것이라 생각했습니다. 또한 빌드와 배포 과정을 좀 더 이해할 수 있을 것 같아 이 방법을 사용해보기로 하였습니다.


SSH

비밀번호 없이 로그인하기

→ 공개/비밀키 사용


클라이언트

ssh-keygen -t rsa

생성시 모든 질문엔 enter

  • 생성된 키 파일
    • id_rsa : 비밀키. 접속할 때 출발노드에서 사용
    • id_rsa.pub : 공개키. 원격 서버에 해당 키를 보낸다.
      키를 보내는 방법으로는 ssh-copy-id와 scp가 있는데, scp는 이미 위에서 방법을 알았으므로 ssh-copy-id를 사용해보겠습니다. 대신 ssh-copy-id방법으로 보내려면 22번 포트를 사용할 수 있어야 합니다.
ssh-copy-id [user]@[hostname]



배포할 원격 서버

위에서 클라이언트가 보낸 과정을 통해 .ssh폴더에 authorized_keys가 생긴 것을 확인할 수 있습니다. 이 파일에 공개키가 저장되어있습니다.

# 제대로 들어왔는지 확인
cat authorized_keys

# 파일의 권한 수정
sudo chmod 600 ~/.ssh/authorized_keys

저는 해당 파일의 권한을 소유자만 읽기,쓰기가 가능하도록 설정하였습니다. 이 부분은 상황에 따라 다르게 적용하시면 될 것 같습니다.

# sshd 데몬 재시작
sudo service sshd restart



scp(secure copy)

: 원격 서버의 파일을 전송하거나 가져오기 위해 사용하는 명령어

ssh 원격 접속 프로토콜을 기반으로 하며, ssh와 동일한 22번 포트를 이용하여 password, identity file을 이용해 안전하게 송수신 가능합니다.


scp 명령어로 local→remote 파일 전송

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



Trouble Shooting

error ) host key verification failed

처음 원격 서버에 ssh로 접속할 때, RSA key fingerprint로 접속 여부를 물어봅니다.

연결하려는 원격 서버에 연결중인지 즉, 신뢰하는 호스트인지 확인하는 의도입니다.

yes를 입력하면 원격 서버를 기반으로 하는 fingerprint가 생성되어 클라이언트의 known-hosts에 저장이 됩니다. 따라서 설정 이후에 host에 접속할 수 있습니다.

~/.ssh 경로에서 cat known_hosts 로 확인을 해보면, ip주소와 공개키가 저장되어 있는것을 확인하실 수 있습니다. 그래서 만약에 해당 정보가 변경된다면 문제가 발생할 수 있어 known_hosts 파일을 수정해야하는 상황도 종종 발생하는 듯 합니다.


error ) Pseudo-terminal will not be allocated because stdin is not a terminal.

pseudo terminal은 터미널처럼 상호작용하여 소통합니다. pipe를 통해 원격으로 ssh를 실행하면 위와 같은 에러가 나올 수 있는데, 이는 터미널처럼 상호작용하지 않아 ssh에 대해 지정된 명령이 없기 때문입니다.

해결방법

  1. -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
  2. bash 명령어 사용

  3. -q 옵션 사용

  4. 단일 명령어 사용

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




📕 Reference

https://www.linuxtutorials.org/Pseudo-terminal-will-not-be-allocated-because-stdin-is-not-a-terminal/

https://tjdrnr05571.tistory.com/13

https://community.home-assistant.io/t/how-to-restart-service-on-a-remote-machine-systemctl-host-pi-ip-command/68495

profile
열심히 공부중입니다😇

0개의 댓글