DevOps/Ansible

[Ansible] 자동으로 known_hosts에 등록하기

[Version 정보]
Ansible 2.9.15
vagrant 2.2.14
CentOS vm='generic/centos8'
Ubuntu vm='ubuntu/trusty64'

Known_hosts란?

이미 알고 있어, 확인하지 않아도 되는 믿을 수 있는 호스트.

 

 

known-hosts를 등록해주는 명령어

Files

Auto_known_hosts.yml

---
- hosts: Ubuntu
  connection: local
  serial: 1
  gather_facts: no

  tasks:
  - name: get known_hosts fingerprint for ubuntu nodes
    command: /usr/bin/ssh-keyscan -t ecdsa {{ ansible_host }}
    register: keyscan

  - name: add ansible_host to known_hosts
    lineinfile:
      name=~/.ssh/known_hosts
      create=yes
      line={{ item }}
    with_items:
      - "{{ keyscan.stdout_lines }}"

- hosts: CentOS
  connection: local
  serial: 1
  gather_facts: no

  tasks:
  - name: get known_hosts fingerprint for ubuntu nodes
    command: /usr/bin/ssh-keyscan -t rsa {{ ansible_host }}
    register: keyscan

  - name: add ansible_host to known_hosts
    known_hosts:
      name: "{{ ansible_host }}"
      key: "{{ item }}"
    with_items:
      - "{{ keyscan.stdout_lines }}"
  • serial : 실행시 node 안에서 한줄씩 천천히 실행 ( 안정성을 위해서)

  • 각 host를 다르게 설정하여 한 이유는 Linux OS마다 ssh known_hosts를 취급하는 법이 다른 것같다. (같은 코드로 host를 all해서 돌리면 error가 난다.)

    error) non-zero return code를 반환하는데 아마 rsa로 타입을 변경해서 CentOS를 구분하면 실행된다. (❗하지만 정상적으로 동작하지않음 이유는 아래에..)

      ansible-server: fatal: [192.168.1.201]: FAILED! => {"ansible_facts": {"discovered_interpreter_python": "/usr/libexec/platform-python"}, "changed": true, "cmd": ["/usr/bin/ssh-keyscan", "-t", "ecdsa", "192.168.1.201"], "delta": "0:00:00.015903", "end": "2020-12-01 12:29:14.365934", "msg": "non-zero return code", "rc": 1, "start": "2020-12-01 12:29:14.350031", "stderr": "# 192.168.1.201:22 SSH-2.0-OpenSSH_8.0", "stderr_lines": ["# 192.168.1.201:22 SSH-2.0-OpenSSH_8.0"], "stdout": "", "stdout_lines": []}

Ubuntu code 과정

  1. ubuntu node에서 ssh-keyscan 명령을 이용해 ECDSA algorithm을 이용해 key값을 생성하고 keyscan이라는 register에 담습니다.

  2. keyscan에 담겨있는 register값을 ~/.ssh/known_hosts에 SSH_KNOWN_HOSTS FILE FORMAT에 맞게 작성합니다.

💁‍♂️tip!) SSH\_KNOWN\_HOSTS FILE FORMAT은 [man(8) sshd](https://linux.die.net/man/8/sshd)의 공식문서를 참조했습니다.

CentOS 8 code 과정

  1. Ubuntu와 같이 ssh-keyscan 명령을 이용하지만 RSA algorithm을 이용하는 차이점이 있습니다. 기존 CentOS 8에서 ssh-keyscan 을 사용하는 명령어 형식은 다음과 같습니다. 하지만 제대로 동작하지 않습니다.

  2. 정상적으로 동작하기 위해서는 위와 같이 ansible의 builtin module인 known_hosts를 사용해야합니다. Ubuntu에서 register를 처리했던 것과 비슷하게 처리합니다.
    (다만, 공식문서에 따르면 key format을 <hostname[,IP]> ssh-rsa <pubkey> 와 같은 형식으로 맞춰야하는 것이 나와있습니다. )

  3. register을 분석해보면,

    ['192.168.1.201 ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDmDy............J31pj03GBjMX6ISb7y/7hOhsgZU='] (type list)

    이렇게 key값이 list형식으로 들어져 있습니다.
    각 list형식에서 하나씩 가져오기 위해서는 "{{ item }}"with_items 를 이용하면 반복적으롤 하나의 요소만 가져올 수 있습니다.

Output

결과적으로 정상적으로 key가 교환된 모습

~/.ssh/known_hosts 파일

Ping test

본 내용은 [심화] 앤서블(Ansible)을 깊이 있게 활용하기 - 조훈님의 강의에서 실습 중 Trouble Shooting한 내용입니다.

'DevOps > Ansible' 카테고리의 다른 글

[Ansible] YAML에서의 multiline - 1  (0) 2021.04.29