Ansible

Ansible 구성 authorized_keys 등록 자동화

Joon0464 2021. 7. 21. 15:58

[심화] 앤서블(Ansible)을 깊이 있게 활용하기 - 인프런 | 학습 페이지 (inflearn.com)

 

[심화] 앤서블(Ansible)을 깊이 있게 활용하기 - 인프런 | 학습 페이지

지식을 나누면 반드시 나에게 돌아옵니다. 인프런을 통해 나의 지식에 가치를 부여하세요....

www.inflearn.com

- authorized keys란?

  • 인증된 키를 뜻함
  • 이미 사용허가를 받아서 믿을 수 있는 사용자를 말한다.
  • 서버가 노드에 접속을 시도하면 노드는 ~/.ssh/authorized_keys 파일 존재를 확인하고 authorized_keys 내용에 접속자의 접속을 허가할 수 있는 정보가 저장되어 있는지 확인하여 접속을 허용한다.

-  authorized keys 자동화 구축 방법 고려

  • authorized_keys에 등록할 ssh 키를 서버에서 생성하여 전달해줘야한다.
  • ssh키는 ssh-keygen 명령어로 생성한다.
  • 일반적으로 공개키(public key, id_rsa.pub)와 사설키(private key, id_rsa.) 을 생성하고 노드에게 ssh키를 전달할 때는 공개키만 전달한다.
  • ssh-keygen을 입력하면 추가로 키보드 입력이 필요하게 되므로 자동화하기 어렵다.
  • 따라서 옵션을 적극 활용하여 ssh-keygen -b 2048 -t rsa -f ~/.ssh/id_rsa -q -N '' 을 자동화에 사용한다.
  • -b는 암호화 수준 -t는 암호화 방식 나머지 옵션은 원하는 경로에 저장하기 위한 옵션이다.

- 자동화 할 때 실패할 수 있는 상황

1. 첫 번째 상황

---
- hosts: localhost
  gather_facts: no
  tasks:
  - name: ssh-keygen
    command: "ssh-keygen -b 2048 -t rsa -f ~/.ssh/id_rsa -q -N ''"
    
- hosts: nodes
  gather_facts: no
  tasks:
  - name: remote copy for authorized_keys
    copy:
      src: /home/vagrant/.ssh/id_rsa.pub
      dest: /home/vagrant/.ssh/authorized_keys

위와 같이 작성하면 id_rsa.pub를 노드에게 복사하여 authorized_keys로 이름을 변경하여 노드의 .ssh/authorized_keys로 저장되게 된다.

이 때 vagrant ssh를 사용하여 노드에 접속하기 위해 존재하던 authorized_keys 기존 파일이 덮어씌워지게 되어 더 이상 vagrant up을 사용할 수 없게 되며 vagrant ssh를 통한 노드 접속을 시도하면 비밀번호를 입력하라고 출력된다.

따라서 copy 모듈을 사용한 자동화는 지양해야한다.

 

2. 두 번째 상황

---
- hosts: localhost
  gather_facts: no
  tasks:
  - name: ssh-keygen
    command: "ssh-keygen -b 2048 -t rsa -f ~/.ssh/id_rsa -q -N ''"
    ignore_errors:yes
  - name: read id_rsa.pub
    command: "cat ~/.ssh/id_rsa.pub"
    register: id_pub
  - name: localhost's debug msg
    debug:
      msg: "{{ id_pub }}"
    
- hosts: nodes
  gather_facts: no
  tasks:
  - name: nodes's debug msg
    debug:
      msg: "{{ id_pub }}"
  - name: remote lineinfile for authorized_keys
    lineinfile:
      dest: /home/vagrant/.ssh/authorized_keys
      line: "{{ id_pub_stdout }}"

복사하면 안되기 때문에 id_rsa.pub를 읽은 후 읽은 내용을 authorized_keys에 쓰는 자동화 작업을 코드로 작성하였다.

하지만 실제로  yml 파일을 실행하면 읽은 id_rsa.pub 파일을 authorized_keys에 제대로 전달하지 못하는 문제가 발생한다.

그 이유는 localhost에서 읽은 id_rsa.pub를 register를 통해 id_pub에 저장했지만 lineinfile을 통해 authorized_keys에 내용이 전달되는 대상은 localhost가 아닌 nodes 이기 때문에 오류가 발생하는 것이다.

 

3. 완성 되었으나 아직 간결하지 않은 상태

---
- hosts: nodes
  gather_facts: no
  tasks:
  - name: ssh-keygen
    connection: local
    command: "ssh-keygen -b 2048 -t rsa -f ~/.ssh/id_rsa -q -N ''"
    ignore_errors: yes
    run_once: true
  - name: read id_rsa.pub
    connection: local
    command: "cat ~/.ssh/id_rsa.pub"
    register: id_pub
    run_once: true
    
- hosts: nodes
  gather_facts: no
  tasks:
  - name: remote lineinfile for authorized_keys
    lineinfile:
      dest: /home/vagrant/.ssh/authorized_keys
      line: "{{ id_pub_stdout }}"

서로 다른 host 간에는 읽은 내용 전달이 안되기 때문에 같은 nodes로 호스틀 맞추고 로컬(ansible-server)에서 실행되야 하는 tasks는 connection: local 을 사용하여 로컬에서만 해당 tasks가 진행되도록 설정했다.

그리고 nodes의 포함된 노드의 개수만큼 tasks가 실행되는 것을 방지하기 위해 run_once: true를 사용하여 한 번만 실행되도록 설정했다.

 

- 최종 완성 Auto_authorized_keys.yml

---
- hosts: nodes
  gather_facts: no

  tasks:
  - name: ssh-keygen
    connection: local
    command: "ssh-keygen -b 2048 -t rsa -f ~/.ssh/id_rsa -q -N ''"
    ignore_errors:yes
    run_once: true
    
  - name: read id_rsa.pub
    connection: local
    command: "cat ~/.ssh/id_rsa.pub"
    register: id_pub
    run_once: true
    
  - name: remote lineinfile for authorized_keys
    lineinfile:
      dest: /home/vagrant/.ssh/authorized_keys
      line: "{{ id_pub_stdout }}"

이와 같이 최종적으로 코드를 간결화하면 authorized_keys 자동 등록을 위한 yml파일 작성이 완료된다.

- Vagrantfile 수정 및 프로비저닝 & 테스트

cfg.vm.provision "file", source: "Auto_authorized_keys.yml", destination: "Auto_authorized_keys.yml"
cfg.vm.provision "shell", inline: "ansible-playbook Auto_authorized_keys.yml --extra-vars 'ansible_ssh_pass=vagrant'", privileged: false

vagrantfile에 Auto_authorized_keys.yml을 ansible-server에 복사하여 이동시키고 플레이북을 실행시키기 위한 설정을 추가한다.

C:\HashiCorp>vagrant provision ansible-server

ansible-server의 변경사항을 적용하기 위해 프로비저닝해준다.

ansible-server에 ssh 접속하여 ansible ping 모듈을 -k 옵션 없이 테스트해보면  정상적으로 Ping이 동작하는 것을 볼 수 있다.