1

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: sudouser@XXX.XXX.XXX.XXX: Permission denied (publickey,password).", "unreachable": true}

What I already tried:

  • connect manually with:
    ssh sudouser@XXX.XXX.XXX.XXX
    => Works fine: connection established!

  • connect manually with:
    ssh -o 'StrictHostKeyChecking=no' sudouser@XXX.XXX.XXX.XXX
    => 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.

  • Have you specified the `private_key_file` in the `ansible.cfg`? And how do you run the ping commando? – Mr. Diba Mar 02 '23 at 10:37
  • 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 Mar 02 '23 at 10:40
  • The ping command is ran from the bash script, just after SSH keygen and SSH-copy-id – Emmanuel FRANCOIS Mar 02 '23 at 10:43
  • 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"}` – Emmanuel FRANCOIS Mar 02 '23 at 10:57

1 Answers1

1

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...