Score:1

Ansible playbook can not connect to remote user through ssh => unreachable & permission denied

la flag

I'm building a complete solution to setup and harden our vps (ubuntu 22.04) with bash script and Ansible playbooks. What I want to do is the following:

  1. Create a custom group "sudogroup" with sudo privileges
  2. Create a new user "sudouser" in this group
  3. Secure SSH connection to this user with keys pair
  4. Execute my Ansible playbook as "sudouser" instead of "root"

I'm doing this with the following bash script:

#---------------------------------------------
# Prepare Vars
#---------------------------------------------
# Remote Server Machine
IPSERVER="XXX.XXX.XXX.XXX"
ROOTUSER_NAME="root"
ROOTUSER_PASSWORD="password1"
#---------------------------------------------
# Sudo Group & User
SUDOGROUP="sudogroup"
SUDOUSER_NAME="sudouser"
SUDOUSER_PASSWORD="password2"
#---------------------------------------------
# SSH Connections
SSHROOTPASS=$ROOTUSER_PASSWORD
SSHCRYPTALGO="ecdsa"    # rsa (regular) - dsa (not recommanded) - ecdsa (best)
SSHCRYPTBYTES="521"     # Strongest: [rsa : 4096] - [dsa: 1024] - [ecdsa: 521]
SSHFILENAME="id_$SSHCRYPTALGO"
#---------------------------------------------
# SSH Connections
SSHCRYPTALGO="ecdsa"    # rsa (regular) - dsa (not recommanded) - ecdsa (best)
SSHCRYPTBYTES="521"     # rsa : 4096 - dsa: 1024 - ecdsa: 521
SSHPORT="22"
SSHROOTCONN="$ROOTUSER_NAME@$IPSERVER"
SSHROOTPASS=$ROOTUSER_PASSWORD
SSHROOTOPTIONS="-p $SSHPORT -tt -o StrictHostKeyChecking=no -o BatchMode=no"
SSHROOTFILENAME="id_$SSHCRYPTALGO"
SSHADMCONN="$SUDOUSER_NAME@$IPSERVER"
SSHADMPASS=$SUDOUSER_PASSWORD
SSHADMFILENAME="id_"$SSHCRYPTALGO"_"$SUDOUSER_NAME
#---------------------------------------------

#---------------------------------------------
# Create a hidden [/home/$SUDOUSER_NAME/.ssh] directory to store SSL keys
sudo mkdir -p ~/.ssh
sudo chmod 700 ~/.ssh
#---------------------------------------------
# Register Remote Server IP in known hosts
sudo ssh-keyscan -H $IPSERVER >> ~/.ssh/known_hosts

#---------------------------------------------
# Create a new SUDO privileged users group & new User on remote server
#---------------------------------------------
sshpass -p "$SSHROOTPASS" ssh $SSHROOTOPTIONS $SSHROOTCONN "bash -s" << ENDSSH01
  stty -echo
  # Backup [sudoers] configuration file to recover, just in case
  cp --archive /etc/sudoers /etc/sudoers-COPY-$(date +"%Y%m%d%H%M%S")
  #---------------------------------------------
  # Create a new group of users
  groupadd $SUDOGROUP
  #---------------------------------------------
  # Add [$SUDOGROUP] to [sudoers] configuration file
  echo "%$SUDOGROUP ALL=(ALL:ALL) ALL" >> /etc/sudoers
  #---------------------------------------------
  # Create a new sudo User named [$SUDOUSER_NAME]
  useradd -m -s /bin/bash -g $SUDOGROUP $SUDOUSER_NAME
  #---------------------------------------------
  # Set password of the new sudo User named [$SUDOUSER_NAME]
  echo "$SUDOUSER_NAME:$SUDOUSER_PASSWORD" | chpasswd
  #---------------------------------------------
  stty echo
  exit
ENDSSH01
#---------------------------------------------


#---------------------------------------------
# Setup SSH Connection between local Client and remote Server
#---------------------------------------------
# Create SSH Keys pair for [sudouser]
sudo ssh-keygen -t $SSHCRYPTALGO -b $SSHCRYPTBYTES -N "" -f ~/.ssh/$SSHADMFILENAME <<< y
sudo ssh-copy-id -i ~/.ssh/$SSHADMFILENAME.pub $SUDOUSER_NAME@$IPSERVER -o StrictHostKeyChecking=no
#---------------------------------------------
# Send a PING to the remote server to check SSH Connection to [sudouser]
sudo ansible all -i inventory -m ping --private-key=~/.ssh/$SSHADMFILENAME
#---------------------------------------------


#---------------------------------------------
# Execute Ansible Playbook to setup remote Ubuntu 18/20/22 Remote Server
#---------------------------------------------
sudo ansible-playbook -i inventory setup_server.yml --private-key=~/.ssh/$SSHADMFILENAME
#---------------------------------------------

The Ansible Inventory file:

[OURVPS]
195.179.193.224

The Ansible playbook starts like this:

#---------------------------------------------
# ANSIBLE PLAYBOOK
#---------------------------------------------
- name: SETUP UBUNTU 22.04 SERVER / VPS
  hosts: OURVPS
  remote_user: sudouser
  become: yes
  become_method: sudo

  #---------------------------------------------
  vars:
  #---------------------------------------------
    # Disable strict host key checking when connecting to remote hosts via SSH
    ansible_ssh_common_args: "-o StrictHostKeyChecking=no"
    ...
  #---------------------------------------------
  tasks:
  #---------------------------------------------
  ...

The bash script executes correctly (group and user are correctly setup) with no error, until it tries to execute the ansible playbook.

The PING command returns:

XXX.XXX.XXX.XXX | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python3"
    },
    "changed": false,
    "ping": "pong"
}

Then, I always receive the same error:

fatal: [XXX.XXX.XXX.XXX]: UNREACHABLE! => {"changed": false, "msg": "Failed to connect to the host via ssh: [email protected]: Permission denied (publickey,password).", "unreachable": true}

What I already tried:

  • connect manually with:
    ssh [email protected]
    => Works fine: connection established!

  • connect manually with:
    ssh -o 'StrictHostKeyChecking=no' [email protected]
    => Works fine: connection established!

Why does this ansible playbook refuse to execute correctly ???
If I can connect manually, then why Ansible can not connect automatically ???

P.S: This question could be a duplicate of other questions available but I did not get any positive insight to match with my case.

Mr. Diba avatar
gq flag
Have you specified the `private_key_file` in the `ansible.cfg`? And how do you run the ping commando?
Emmanuel FRANCOIS avatar
la flag
This is my ansible.cfg: ```[ssh_connection] scp_if_ssh=True host_key_checking = False``` How to specify the private key in it ?
Emmanuel FRANCOIS avatar
la flag
The ping command is ran from the bash script, just after SSH keygen and SSH-copy-id
Emmanuel FRANCOIS avatar
la flag
I just added the following line into ansible.cfg: `private_key_file = /root/.ssh/id_ecdsa_sudouser` and the following var to my ansible playbook: `ansible_ssh_private_key_file: "/root/.ssh/id_ecdsa_sudouser"` This results in a new error: `fatal: [XXX.XXX.XXX.XXX]: FAILED! => {"msg": "Missing sudo password"}`
Score:1
la flag

Ok, I found the solution: I added the two following vars to my Ansible playbook:

vars:
    ansible_ssh_private_key_file: "/root/.ssh/id_ecdsa_sudouser"
    ansible_sudo_pass: "password2"

Now, the ansible playbook runs correctly, without errors...

mangohost

Post an answer

Most people don’t grasp that asking a lot of questions unlocks learning and improves interpersonal bonding. In Alison’s studies, for example, though people could accurately recall how many questions had been asked in their conversations, they didn’t intuit the link between questions and liking. Across four studies, in which participants were engaged in conversations themselves or read transcripts of others’ conversations, people tended not to realize that question asking would influence—or had influenced—the level of amity between the conversationalists.