ansible을 통해 호스트 SSH 키를 생성하는 방법은 무엇입니까?


11

사용 가능한 (및 ssh-keygen)을 통해 소수의 원격 서버에서 ssh 호스트 키를 다시 생성하려고하는데 파일이 표시되지 않는 것 같습니다. 플레이 북이 정상적으로 실행되지만 리모콘의 파일은 변경되지 않습니다.

echo -e이 리모컨은 우분투 14.04를 실행 중이며 python-pexpect사용 가능한 버전이 정확하지 않기 때문에 해커 에게 의지해야합니다 .

내가 무엇을 놓치고 있습니까? 내 플레이 북과 출력은 다음과 같습니다.

플레이 북

---
- hosts: all
  become: true
  gather_facts: false

  tasks:
    - name: Generate /etc/ssh/ RSA host key
      command : echo -e 'y\n'|ssh-keygen -q -t rsa -f /etc/ssh/ssh_host_rsa_key -C "" -N ""
      register: output
    - debug: var=output.stdout_lines

    - name: Generate /etc/ssh/ DSA host key
      command : echo -e 'y\n'|ssh-keygen -q -t dsa -f /etc/ssh/ssh_host_dsa_key -C "" -N ""
      register: output
    - debug: var=output.stdout_lines

    - name: Generate /etc/ssh/ ECDSA host key
      command : echo -e 'y\n'|ssh-keygen -q -t ecdsa -f /etc/ssh/ssh_host_ecdsa_key -C "" -N ""
      register: output
    - debug: var=output.stdout_lines

산출

$ ansible-playbook ./playbooks/ssh-hostkeys.yml -l myhost.mydom.com, 
SUDO password: 

PLAY [all] **********************************************************************************************

TASK [Generate /etc/ssh/ RSA host key] ******************************************************************
changed: [myhost.mydom.com]

TASK [debug] ********************************************************************************************
ok: [myhost.mydom.com] => {
    "output.stdout_lines": [
        "y", 
        "|ssh-keygen -q -t rsa -f /etc/ssh/ssh_host_rsa_key -C  -N "
    ]
}

TASK [Generate /etc/ssh/ DSA host key] ******************************************************************
changed: [myhost.mydom.com]

TASK [debug] ********************************************************************************************
ok: [myhost.mydom.com] => {
    "output.stdout_lines": [
        "y", 
        "|ssh-keygen -q -t dsa -f /etc/ssh/ssh_host_dsa_key -C  -N "
    ]
}

TASK [Generate /etc/ssh/ ECDSA host key] ****************************************************************
changed: [myhost.mydom.com]

TASK [debug] ********************************************************************************************
ok: [myhost.mydom.com] => {
    "output.stdout_lines": [
        "y", 
        "|ssh-keygen -q -t ecdsa -f /etc/ssh/ssh_host_ecdsa_key -C  -N "
    ]
}

PLAY RECAP **********************************************************************************************
myhost.mydom.com : ok=6    changed=3    unreachable=0    failed=0  

답변:


14

'y'를 ssh-keygen에 파이프해야하는 유일한 이유는 명령이 기존 파일을 바꾸는 것입니다. 내 생각에 이것은 구성 관리 도구에서 무언가를 수행하는 좋은 방법이 아닙니다.

dem 등원이되도록 작업을 조정해야합니다. 특히 creates: filename명령에 를 추가하면 새 키는 해당 플레이 북을 실행할 때마다 교체되지 않고 존재하지 않는 경우에만 생성됩니다.

---
- hosts: all
  become: true
  gather_facts: false

  tasks:
  - name: Generate /etc/ssh/ RSA host key
    command : ssh-keygen -q -t rsa -f /etc/ssh/ssh_host_rsa_key -C "" -N ""
    args:
      creates: /etc/ssh/ssh_host_rsa_key

  - name: Generate /etc/ssh/ DSA host key
    command : ssh-keygen -q -t dsa -f /etc/ssh/ssh_host_dsa_key -C "" -N ""
    args:
      creates: /etc/ssh/ssh_host_dsa_key

  - name: Generate /etc/ssh/ ECDSA host key
    command : ssh-keygen -q -t ecdsa -f /etc/ssh/ssh_host_ecdsa_key -C "" -N ""
    args:
      creates: /etc/ssh/ssh_host_ecdsa_key

어떤 이유로 키가 너무 오래된 키 등을 교체하려는 경우 다른 작업을 추가하여 제거 할 수 있습니다. 간단한 삭제입니다

- file:
    state: absent:
    path: "{{item}}"
  loop:
  - /etc/ssh/ssh_host_rsa_key
  - /etc/ssh/ssh_host_dsa_key
  - /etc/ssh/ssh_host_ecdsa_key

특정 시간 이전에 생성 된 파일을 삭제하려면 stat 모듈을 사용하여이 파일에 대한 세부 사항을 검색 when하고 특정 날짜 또는 그보다 오래된 파일 을 선택적으로 제거하도록 설정 조건을 설정할 수 있습니다.


dem 등식을 유지하는 것에 대한 생각에 큰 예와 감사합니다. 유스 케이스의 경우 복제 된 가상 머신을 프로비저닝하므로 항상 덮어 쓸 키가 있습니다. 난 그냥 제거하고 교체하려면 핵 옵션이 필요합니다.
서버 오류

항상 제거하기를 원한다면 아마도 file: state:absent ...ssh-keygen에 물건을 파이핑 하는 접근법을 시도 했을 것입니다 . 그다지 큰 차이는 없지만 말입니다.
Zoredache

그래. 더 이해가 되네요 absent며칠 전에는 몰랐습니다 . 효과적으로 키를 다시 생성하기 전에 파일을 삭제합니다. 훨씬 명확한 접근 방식입니다. 감사.
서버 오류

6

ansible command모듈 은 쉘을 통해 명령을 전달하지 않습니다 . 이것은 파이프와 같은 쉘 연산자를 사용할 수 없다는 것을 의미하므로 출력에 파이프 기호가 표시됩니다. ansible에 관한 한, echo나머지 행을 모두 인수로 하여 명령 을 실행 했습니다 echo.

쉘로 처리 된 명령 행이 필요한 경우 대신을 사용하십시오shellcommand .

그리고 ssh 호스트 키를 재생성하는 더 좋은 방법이 있어야하지만 지금은 찾을 수 없습니다 ...


쉘 대 명령 팁 주셔서 감사합니다 (지금은 잘 작동) 나는 몰랐다 - ansible에 여전히 꽤 새로운
서버 오류

이전 키를 제거하고 다시 시작하면 마지막 명령문 (적어도 CentOS / RHEL에서)과 관련하여 데몬 호스트 키가 다시 생성됩니다. 어쨌든 서비스를 다시 시작해야하므로 이것이 다소 나아 보입니다.
Aaron Copley

@AaronCopley 나는 배포 서비스보다 Ansible 역할을 더 많이 언급했습니다. 대부분의 주요 배포판에는 ssh 호스트 키를 생성하는 시스템 서비스가 있다는 것을 알고 있습니다. 불행히도이 서비스는 미묘한 배포 판별 차이점이 있습니다 (CentOS와 Fedora 간에는 다름). 역할은 그 모든 것을 캡슐화하는 좋은 방법이지만, 나는 하나의 손을 찾을 수 없습니다.
Michael Hampton

걱정하지 마세요. 내가 언급 할 것이라고 생각했습니다. (아직 알 수 있지만 OP는 그렇지 않을 수 있습니다.)
Aaron Copley

@AaronCopley-우연히, 이것이 내가 한 일입니다. echo ...비트는 두 번째 실행 (제가 테스트 한 년 후에 일을하지 않았다 /tmp/어떤 키가 주위에 처음 존재하지 않았다). 언급했듯이 먼저 호스트 키를 제거하고 새 키를 생성하는 데 의존했습니다. 키가 자동으로 재생성되는 한 배포에 따라 다릅니다. 맞습니까? 모든 Linux 배포판에서 systemd를 사용하는 것은 아닙니다.
서버 오류

2

이 작업에는 특수 모듈을 사용하십시오.

- name: Generate an OpenSSH keypair with the default values (4096 bits, rsa)
  openssh_keypair:
    path: /home/youruser/.ssh/id_rsa
    owner: youruser
    group: youruser

- name: Fix owner of the generated pub key
  file:
    path: /home/youruser/.ssh/id_rsa.pub
    owner: youruser
    group: youruser

이것들은 ssh 호스트 키가 아닙니다
KumZ

1

죄송하지만 작업에서 "creates"를 사용할 수 없습니다. 다음과 같은 오류가 발생했습니다.

ERROR! 'creates' is not a valid attribute for a Task

결과적으로 다음 작업을 사용합니다.

- name: remove existing ssh_host keys
  file: path={{ item }} state=absent
  with_items:
    - "/etc/ssh/ssh_host_rsa_key"
    - "/etc/ssh/ssh_host_dsa_key"
    - "/etc/ssh/ssh_host_ecdsa_key"

- name: Generate /etc/ssh/ RSA host key
  command : ssh-keygen -q -t rsa -f /etc/ssh/ssh_host_rsa_key -C "" -N ""

- name: Generate /etc/ssh/ DSA host key
  command : ssh-keygen -q -t dsa -f /etc/ssh/ssh_host_dsa_key -C "" -N ""

- name: Generate /etc/ssh/ ECDSA host key
  command : ssh-keygen -q -t ecdsa -f /etc/ssh/ssh_host_ecdsa_key -C "" -N ""

2
현재 버전의 Ansible을 사용하십시오.
Michael Hampton

당신은 맞습니다, 내 Ansible 버전은 약간 오래된 것입니다 : 2.0.0.2 ... (Ubuntu 16.04에서). 나는 바꿔야한다!
MaxiReglisse

1

@Zoredache는 정답을 가지고 있지만 Ansible의 최신 버전에 대해서는 @MaxiReglisse로 표시되지 않습니다. 대신 다음 코드를 사용하십시오.

---
- hosts: all
  become: true
  gather_facts: false

  tasks:
  - name: Generate /etc/ssh/ RSA host key
    command : ssh-keygen -q -t rsa -f /etc/ssh/ssh_host_rsa_key -C "" -N ""
    args:
      creates: /etc/ssh/ssh_host_rsa_key

1

다른 옵션은 사용자 모듈 을 사용하는 것 입니다. 이것의 긍정적 인 측면은 dem 등식 작업을 얻는다는 것입니다. 다음은 localhost에서 ssh 키를 생성하는 방법의 예입니다.

- name: Generate ssh keys
  local_action:
    module: "user"
    name: "{{ lookup('env','USER') }}"
    generate_ssh_key: true
    ssh_key_type: "{{ item.0 }}"
    ssh_key_bits: "{{ item.1 }}"
    ssh_key_file: "{{ playbook_dir }}/{{ item.0 }}_{{ item.1 }}_key"
  with_together:
  - [ 'rsa', 'dsa' ]
  - [ 2048, 1024 ]
  loop_control:
    label: "{{ item.0 }}_{{ item.1 }}_key"

- name: Copy generated ssh keys to remote machine
  copy:
    src: "{{ playbook_dir }}/{{ item.0 }}_{{ item.1 }}_key"
    dest: "/etc/ssh/ssh_host_{{ item.0 }}_key{{ item.1 }}"
  with_nested:
  - [ 'rsa', 'dsa' ]
  - [ '', '.pub' ]
  notify:
  - Restart sshd
  loop_control:
    label: "/etc/ssh/ssh_host_{{ item.0 }}_key{{ item.1 }}"

1
호스트 키가 아닌 사용자 키에 해당되지 않습니까?
MadHatter

호스트 키에도 실제로 사용할 수 있으므로 호스트 키에도 사용할 수 있습니다. 이 모드 시행에 SELinux를 사용하는 경우 그냥 SELinux에 컨텍스트를 복원하는 것을 잊지 마세요
HeroFromEarth

당신이 할 수있는 문서에서 나에게 분명하지 않습니다. 답을 다시 작성하여 작성중인 호스트 키를 명시 적으로 표시하면 다운 보트를 제거합니다.
MadHatter

좋아, 어쩌면 불분명했을 것입니다. 원격 컴퓨터에서 이러한 키를 복사하는 방법을 설명하는 다른 작업을 추가했습니다. 물론 내 경우에만 (클러스터의 경우 몇 대의 컴퓨터에 동일한 키가 필요하므로 localhost에서 생성해야 함) 'user'모듈을 사용하여 ssh 서버의 키를 생성 할 수 있다고 확신합니다 원격 시스템 ( 'ssh_key_file'봐)
HeroFromEarth

나는 그것이 여전히 해킹 이외의 것이 아닌지 확실하지 않습니다 (최소한 한 명의 사용자가 호스트 개인 키의 사본을 남겨두고 있기 때문에!). 그러나 적어도 요청 된대로 질문에 대답하는 것이기 때문에 내 것을 제거했습니다. 공감.
MadHatter

0

openssh_keypair 및 certified_key 모듈을 사용하여 키를 가능한 호스트에 저장하지 않고 동시에 키를 작성 및 배치하십시오.

- openssh_keypair:
    group: root
    owner: root
    path: /some/path/in/your/server
    register: ssh_key

- name: Store public key into origin
  delegate_to: central_server_name
  authorized_key:
     key: "{{ssh_key.public_key}}"
     comment: "{{ansible_hostname}}"
     user: any_user_on_central
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.