리셋 되지 말자

[Ansible] ssh key 관련 정리 - ansible 명령어에 private key 지정 본문

Infra

[Ansible] ssh key 관련 정리 - ansible 명령어에 private key 지정

kyeongjun-dev 2021. 6. 11. 15:14

ssh key 동작 방식

대충 ssh key 생성부터 public key 배포하고, password 없이 로그인 자동화 하는 과정을 생각해보자
우선, private key와 public key를 분배하는 과정부터 생각해보자.

 

 

Private key, Public key 생성과 분배

Ansible Server가 Ansible Client001에 접속해서 작업을 해야하는 상황을 가정한다. 즉, Ansible Server에서 패스워드 입력 없이  Ansible Client001에 접속이 가능해야 한다.

 

1. ssh key 생성

- Ansible Server에서 key 생성

ssh-keygen -t rsa
Generating public/private rsa key pair.
Enter file in which to save the key (/home/vagrant/.ssh/id_rsa):                      
Enter passphrase (empty for no passphrase): 
Enter same passphrase again: 
Your identification has been saved in /home/vagrant/.ssh/id_rsa.
Your public key has been saved in /home/vagrant/.ssh/id_rsa.pub.
The key fingerprint is:
SHA256:PxzrGtpaXVFjlpqBfzMhIFfc9Aj4u8oD5vDG0acP4PU vagrant@ansible-server
The key's randomart image is:
+---[RSA 2048]----+
|        . o*oo*. |
|         oo +=++ |
|           o.=...|
|            =.+  |
|        S.o .o o |
|      ..+*.=o    |
|       *+oBoE.   |
|       +=+oo.    |
|      ooo.++.    |
+----[SHA256]-----+

위처럼 ssh-keygen 명령어를 사용하여 아무것도 입력하지 않고 key를 생성한다.

 

- Ansible Server의 ~/.ssh/ 디렉토리 확인

ls ~/.ssh/
authorized_keys  id_rsa  id_rsa.pub

그러면 id_rsa라는 private key와 id_rsa.pub 라는 public key가 생성된다.
여기서 Ansible Client001에 패스워드 입력 없이 로그인하기 위해서 전송해야 하는 건 public key인 id_rsa.pub 이다.

 

- 현재 상태

 

2. public key 전송

- Ansible Server에서 public key 전송

ssh-copy-id -i ~/.ssh/id_rsa.pub vagrant@192.168.56.101
/usr/bin/ssh-copy-id: INFO: Source of key(s) to be installed: "/home/vagrant/.ssh/id_rsa.pub"
The authenticity of host '192.168.56.101 (192.168.56.101)' can't be established.
ECDSA key fingerprint is SHA256:X+QYC/t9t7m0vi9EB9/Itd0JyORUYJSvUEtNlvfvBc4.
Are you sure you want to continue connecting (yes/no)? yes
/usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed
/usr/bin/ssh-copy-id: INFO: 1 key(s) remain to be installed -- if you are prompted now it is to install the new keys
vagrant@192.168.56.101: Permission denied (publickey).

일단, ECDSA key fingerprint 등록 여부는 '진짜 연결할거냐?'를 묻는다. 처음 연결하니까 물어보는 것인데, 이건 'ssh-keyscan'을 통해 자동화할 수 있다. 이건 아래의 참고 링크를 확인한다. (yes를 하면, Ansible Server의 ~/.ssh/ 경로에 known_hosts 파일이 생성되고, 거기에 192.168.56.101에 대한 정보가 등록된다. 등록되고나면, 다시 접속을 할때 ECDSA key를 등록하겠냐고 물어보지 않는다.)
참고 : https://not-to-be-reset.tistory.com/431

그 아래를 보면 'Permission denied (publickey)'라고 출력된다. 이는 pubic key를 전송하고자 하는 대상 서버(Ansible Client001)의 ssh option을 변경하여, Password를 입력할 수 있도록 해줘야 한다.

 

- Ansible Client001의 ssh config 옵션 변경

sudo vi /etc/ssh/sshd_config

 

 

PasswordAuthentication yes

위처럼 PasswordAuthentication no를 yes로 변경한다.

 

- Ansible Client001의 ssh 재시작

sudo service ssh restart

ssh 를 재시작 해준다.

 

- public key 전송 재시도 (Ansible Server에서 ssh-copy-id 명령어 수행)

ssh-copy-id -i ~/.ssh/id_rsa.pub vagrant@192.168.56.101
/usr/bin/ssh-copy-id: INFO: Source of key(s) to be installed: "/home/vagrant/.ssh/id_rsa.pub"
/usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed
/usr/bin/ssh-copy-id: INFO: 1 key(s) remain to be installed -- if you are prompted now it is to install the new keys
vagrant@192.168.56.101's password: 

Number of key(s) added: 1

Now try logging into the machine, with:   "ssh 'vagrant@192.168.56.101'"
and check to make sure that only the key(s) you wanted were added.

 

 

패스워드를 입력하여 접속에 성공했다.

 

- Ansible Client001 확인

ls ~/.ssh/
authorized_keys

~/.ssh/ 경로에 'authorized_keys' 파일이 생성된 것을 확인할 수 있다.

 

- Ansible Client001의 authorized_keys 파일 내용 확인

cat ~/.ssh/authorized_keys 
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC0ADDTRh/vGlP58dNdflZNc60sVpVo1IbmctLuK2XKAALbRbMDVwEp/6WBnuCuuTHJH5HSeT1xqwePSm+6DNIWV/TJ2RWY53RMIuMlaz4JlkSAnvgc5iXlVYaURiCFql3N5QclMEUk76BU8cNPKDDH1LKd+zHDdq/aAxveJpRndg11Xeqmj/bIdOn/A2/sHm1WA3OEXZOjXcOrXnpDiz1jweKX8i+YM97B2Kqek/uPQMO9H8DG8+9UQdNpHR24uXockkAnNVltJQqIOJHVNkLsHGDC7N8J/1Zrqa1GtLfzFR9c3QjvlgjPLFRgJvC9mpx5sgkjZ7jANGa61zUg9LoZ vagrant@ansible-server

Ansible Server에서 생성한 id_rsa.pub 의 내용이 등록되어 있는걸 확인할 수 있다.

 

- 현재 상태

 

 

SSH 접속 테스트

- Ansible Server 에서 Ansible Client001 로 접속

ssh 192.168.56.101
Welcome to Ubuntu 18.04.5 LTS (GNU/Linux 4.15.0-143-generic x86_64)

 * Documentation:  https://help.ubuntu.com
 * Management:     https://landscape.canonical.com
 * Support:        https://ubuntu.com/advantage

  System information as of Fri Jun 11 05:52:17 UTC 2021

  System load:  0.0               Processes:             97
  Usage of /:   2.7% of 38.71GB   Users logged in:       1
  Memory usage: 6%                IP address for enp0s3: 10.0.2.15
  Swap usage:   0%                IP address for enp0s8: 192.168.56.101




New release '20.04.2 LTS' available.
Run 'do-release-upgrade' to upgrade to it.


Last login: Fri Jun 11 05:30:41 2021 from 10.0.2.2

비밀번호 등 아무것도 묻지않고 바로 접속할 수 있다. (현재 Ansible Server 에 접속중인 계정이름과, 접속하려는 Ansible Client001의 계정이름이 다르면 ssh client001-id@192.168.56.101 이런식으로 계정이름을 명시해주면 된다.)

 

Ansible ping 테스트

- Ansible Server의 ansible hosts 파일에 Ansible Client001 등록

vi /etc/ansible/hosts

[clients]
192.168.56.101

직접 위처럼 작성해준다.

 

- ping 모듈을 이용한 ping 테스트

ansible clients -m ping
192.168.56.101 | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python3"
    }, 
    "changed": false, 
    "ping": "pong"
}

Ansible Server의 host 파일에 그룹으로 명시한 'clients'에 ping 테스트를 진행한다. 위처럼 SUCCESS 가 결과로 출력되면, Ansible Server가 ssh접속을 통해 Ansible Client001로 접속하여, 작업을 정상적으로 진행할 수 있는 상태임을 의미한다.

 

id_rsa의 이름 변경

- Ansible Server에서 수행

mv ~/.ssh/id_rsa ~/.ssh/my_private_key
vagrant@ansible-server:~$ ls ~/.ssh/
authorized_keys  id_rsa.pub  known_hosts  my_private_key

이 상태에서 Ansible Server의 ~/.ssh/ 경로에 있는 id_rsa 라는 이름의 private key 파일의 이름을 변경한다.

 

id_rsa 이름을 변경한 뒤, ssh 접속 테스트

- Ansible Server 에서 수행

ssh 192.168.56.101
vagrant@192.168.56.101's password:

 id_rsa 이름이었을 때는 password를 묻지 않았는데, password를 입력하라고 표시된다.
이는 ssh로 접속할 때, 리눅스에서 자동으로 ~/.ssh/ 경로에 있는 id_rsa, id_dsa 등의 특정한 이름을 가진 private key를 사용하기 때문이라고 한다. (아래 참고)

@therobyouknow You do not have to create a unique key pair for every machine. Usually you have few keys, and append the public key of one of the keys to the .ssh/authorized_keys file on the remote machines. If you use the standard .ssh/id_rsa file name (or id_dsa, id_ecdsa or the recent id_ed25519), then ssh will try this automatically and you do not need to specify IdentityFile in your config (or the -i path/to/id_file parameter for ssh).
 – 
Lekensteyn
 
Feb 27 '14 at 16:04
https://askubuntu.com/questions/30788/does-ssh-key-need-to-be-named-id-rsa

 

- Ansible Server에서 private key를 지정하여 ssh 접속

ssh -i ~/.ssh/my_private_key 192.168.56.101
Welcome to Ubuntu 18.04.5 LTS (GNU/Linux 4.15.0-143-generic x86_64)

 * Documentation:  https://help.ubuntu.com
 * Management:     https://landscape.canonical.com
 * Support:        https://ubuntu.com/advantage

  System information as of Fri Jun 11 06:05:45 UTC 2021

  System load:  0.0               Processes:             100
  Usage of /:   2.7% of 38.71GB   Users logged in:       1
  Memory usage: 6%                IP address for enp0s3: 10.0.2.15
  Swap usage:   0%                IP address for enp0s8: 192.168.56.101




New release '20.04.2 LTS' available.
Run 'do-release-upgrade' to upgrade to it.


Last login: Fri Jun 11 05:57:24 2021 from 192.168.56.100

-i 옵션으로 어떤 private key를 이용하여 ssh 접속을 할지 지정할 수 있다. 이렇게하면 패스워드를 입력하지 않고 자동으로 로그인이 가능하다.

 

id_rsa 이름을 변경한 뒤, ansible ping 테스트

- Ansible Server에서 수행

ansible clients -m ping
192.168.56.101 | UNREACHABLE! => {
    "changed": false, 
    "msg": "Failed to connect to the host via ssh: vagrant@192.168.56.101: Permission denied (publickey,password).", 
    "unreachable": true
}

id_rsa 이름을 my_private_key로 바꾼 뒤에는 ansible ping 테스트에 실패한다.
그렇다면 private_key 이름을 무조건 id_rsa, id_dsa 이런 형태로 해야하나? 그렇지는 않다.

 

- Ansible Server에서 private key를 지정하여 ping 테스트 수행

ansible clients -m ping --private-key ~/.ssh/my_private_key 
192.168.56.101 | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python3"
    }, 
    "changed": false, 
    "ping": "pong"
}

ansible에서도 --private-key라는 옵션으로 특정 private key를 지정하여 명령어를 수행할 수 있다.
참고 : https://docs.ansible.com/ansible/latest/user_guide/connection_details.html

 

후기

이제 다시는 ssh 설정으로 고생하지 말자...

Comments