태그 보관물: ssh

SSH service config 일일이 써주기 귀찮다

IP 끝자리만 다른 일곱 대의 서버가 있다. IP를 제외한 대부분의 설정은 동일한데 ~/.ssh/config file을 편집하다 보니 파일이 장황해 지고 관리하기가 힘들어졌다. ssh_config를 찾아보니 %h가 “remote host name”을 의미하기 때문에 이것을 이용해서 간단히 여러 서버에 대한 ssh config를 작성할 수 있다고 한다.

즉, 다음과 같이 IP의 마지막 자리만 다른 7개의 서버가 있다고 할 때,

Host 1
  HostName 123.456.789.1
  User litcoder
  Port 22

Host 2
  HostName 123.456.789.2
  User litcoder
  Port 22
  
Host 3
  HostName 123.456.789.3
  User litcoder
  Port 22

Host 4
  HostName 123.456.789.4
  User litcoder
  Port 22

Host 5
  HostName 123.456.789.5
  User litcoder
  Port 22

Host 6
  HostName 123.456.789.6
  User litcoder
  Port 22  

Host 7
  HostName 123.456.789.7
  User litcoder
  Port 22

이 것들을 remote host를 의미하는 %h를 이용해서 다음과 같이 간단히 할 수 있다.

Host 1 2 3 4 5 6 7
  HostName 123.456.789.%h
  User litcoder
  Port 22

[Tip] 포트 포워딩 설정 상태에서 VNC SSH Tunneling

VNC SSH Tunneling에 대해 다룬 적이 있었는데, macOS에서 기본 제공되는 Screen Sharing 같은 app으로 접속하려면 SSH 터널링을 설정하는 GUI가 없으므로 해당 포스팅의 “SSH Tunneling 설정이 없는 경우” 항목의 안내에 따라 다음과 같은 명령어를 터미널에 입력하고 localhost의 5999번 포트로 연결을 시도하면 된다고 했었다.

# SSH 터널링.
# 22번 SSH 포트를 통해 리모트의 5901번 VNC 포트를 로컬의 5999번 포트에 연결
ssh -L 5999:localhost:5901 <user_id>@<vnc_server_ip>

그럼 만약 22번이 아닌 포트 포워딩을 사용하고 있는 경우라면 어떻게 해야 할까?

사내에 있는 워크스테이션들에 각각 65530 부터 65531까지 포트로 access할 때 포워딩이 이루어 지도록 설정해 둔 상태라고 하면, 22번 포트가 아닌 특정한 포트로 포워딩을 수행하고 있으므로 이 값을 -p 옵션과 함께 작성해 주어야 한다. 예를 들어 포워딩하고 있는 포트의 번호가 65530이고 이를 통해 5901에서 돌고 있는 VNC를 내 localhost의 5999번 포트에 연결하고자 한다면 명령어는 다음과 같다.

# SSH 터널링.
# 65530번 SSH 포트를 통해 리모트의 5901번 VNC 포트를 로컬의 5999번 포트에 연결
ssh -L 5999:localhost:5901 -p 65530 <user_id>@<vnc_server_ip>

그리고 나서 macOS의 Screen Sharing에서는 다음과 같이 설정하고 VNC로 접속한다.

명령어가 너무 길다면

~/.ssh/config 환경 설정파일에 LocalForward를 다음과 같이 추가해 주면 매번 긴 명령어를 타이핑하지 않아도 된다.

# ~/.ssh/config
Host <host_name>
  HostName <vnc_server_ip>
  Port 65530
  User <user_id>
  LocalForward 5999 localhost:5901

이후 부터는 터미널에서 간단히 ssh <host_name> 명령어만 수행해도 Screen Sharing을 통해 VNC로 접속할 수 있다.

Shell drop이 되지 않을 때 원격서버 재시동

원격 서버의 시스템 노드가 망가졌거나 과도한 task 실행으로 ssh로 접근할 때 제대로 shell을 drop하지 못하는 경우가 종종 생긴다.

ssh는 원격 서버에서 실행할 명령어를 인자로 받을 수 있지만 ls같은 단순한 명령어와는 달리 reboot 명령어를 수행하려면 sudo 권한을 접근하기 위한 비밀번호 입력을 필요로 한다.

비록 ssh가 “Secure SHell”이라고는 해도 일반적인 shell처럼 상호작용을 위한 비밀번호 입력 창을 대기해 주지는 않는다.

오류 메세지를 보면 다행히도 sudo는 표준입력으로 부터 비밀번호를 읽어 들이는 -S 옵션을 지원한다. 따라서 비밀번호를 표준출력으로 내보내는 명령어를 묶어서 함께 전송하면 관리자 권한으로 명령어를 실행할 수 있다.

# 비밀번호를 echo를 이용해서 표준출력으로 내보내고 sudo 명령어를 실행시킨다.
ssh <ssh_server> "echo <비밀번호> | sudo -S reboot"

다만, 이렇게 하면 history에 관리자 비밀번호가 노출되므로 동작한 후에는 history를 삭제해 주자.