Ansible : How to handle first login forced password change and push an ssh-key

Viewed 1574

Using ansible to hardenize and configure servers raspberry-pi (arm64), everything works ok, but I need to manually login, change password and the push an ssh key to make my playbook work.

current process.

  1. Fresh installed Ubuntu 20.04
  2. First login user and password ubuntu
  3. SO force to change password, so I need to fill 3.1 current password 3.2 new password 3.3 password confirmation
  4. ssh-copy-id -i my sshkey ubuntu@server
  5. run my playbook to hardenize and do the rest of the job.

¿Is there any way to perform steps 1 to 4 through ansible instead of only manually?

I was thinking to get this done with expect but as per my understanding it only will work after ansible has been authenticated.

2 Answers

By default, ansible will first connect to the host for gathering facts. If host is unable to be connected, ansible will return failed and stop.

My strategy is disable gathering facts to prevent connection failed. Now we can use expect to tackle the first login process, and set the public key. Finally gather facts with setup if you need it.

- hosts: hosts
  gather_facts: false
  tasks:
    - name: "Check if host is reachable"
      wait_for:
        timeout: 0
      register: connect_rs
      ignore_unreachable: yes

    - when: connect_rs is unreachable
      name: "Try first login and change the password"
      delegate_to: localhost
      expect:
        command: sshpass -p {{ ansible_first_login_password }} ssh {{ ansible_ssh_common_args }} {{ ansible_user }}@{{ inventory_hostname }}
        timeout: 10
        responses:
          "Current password:": "{{ ansible_first_login_password }}"
          "New password:": "{{ ansible_password }}"
          "Retype new password:": "{{ ansible_password }}"


    - name: "Setup the public key authentication"
      authorized_key:
        state: present
        user: "{{ ansible_user }}"
        key: "{{ public_key }}"

    - name: "Gather facts about host"
      setup:

You can use sshpass the first time, so that you push your key: and then work with a ssh key, and no pass from that point on:

sshpass -p PASSWORD ssh -o StrictHostKeyChecking=no root@server "echo key >> ~/.ssh/authprized_keys"

You can adjust the command for ssh any way you like, but I think the idea is clear?

Related