I use Packer to build VirtualBox images, with the Ansible provisioner to set up the images. The builder step creates a temporary user (ssh_username
and ssh_password
). The Ansible provisioner runs using this temporary user. I, of course, want to get rid of this user after it's set up our more secure public key-only user. So I added a second Ansible provisioning step that connects as the secure user and removes the insecure user. Or at least that was the plan. However, Ansible via packer is unable to actually connect to the VM using this method.
Here is the relevant portion of the packer.json file:
"provisioners": [
{
"type": "ansible",
"playbook_file": "playbooks/image/image.yml",
"groups": [
"{{user `ansible_group`}}"
],
"user": "vagrant",
"extra_arguments": [
"--vault-password-file", "scripts/get-vault-password.sh",
"-e", "global_configuration_user={{user `configuration_user`}}",
"-e", "global_deployment_user={{user `deployment_user`}}",
"-e", "ansible_ssh_pass=vagrant",
"-vvvvv"
]
},
{
"type": "ansible",
"playbook_file": "playbooks/image/removeVagrant.yml",
"groups": [
"{{user `ansible_group`}}"
],
"user": "{{user `configuration_user`}}",
"extra_arguments": [
"--vault-password-file", "scripts/get-vault-password.sh",
"-e", "global_configuration_user={{user `configuration_user`}}",
"-e", "global_deployment_user={{user `deployment_user`}}",
"-e", "ansible_ssh_private_key_file=~/.ssh/id_{{user `configuration_user`}}_rsa",
"-vvvvv"
]
}
],
The first provisioning step works without issue. It's the second one that fails with permission denied. Ansible is trying to execute the following SSH command:
ssh -vvv -C -o ControlMaster=auto -o ControlPersist=60s -o StrictHostKeyChecking=no -o Port=37947 -o 'IdentityFile="/home/redacted/.ssh/id_rsa"' -o KbdInteractiveAuthentication=no -o PreferredAuthentications=gssapi-with-mic,gssapi-keyex,hostbased,publickey -o PasswordAuthentication=no -o User=redacted -o ConnectTimeout=10 -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -o ControlPath=/home/redacted/.ansible/cp/ansible-ssh-%h-%p-%r 127.0.0.1 '/bin/sh -c '"'"'( umask 77 && mkdir -p "` echo ~/.ansible/tmp/ansible-tmp-1491233126.24-276699777493633 `" && echo ansible-tmp-1491233126.24-276699777493633="` echo ~/.ansible/tmp/ansible-tmp-1491233126.24-276699777493633 `" ) && sleep 0'"'"''
The relevant part of the SSH debug output is:
debug1: SSH2_MSG_NEWKEYS received
debug2: key: /home/redacted/.ssh/id_rsa, explicit, agent
debug2: key: redacted
debug2: key: redacted
debug2: key: redacted
debug2: key: redacted
debug2: key: redacted
debug2: key: redacted
debug2: key: redacted
debug3: send packet: type 5
debug3: receive packet: type 6
debug2: service_accept: ssh-userauth
debug1: SSH2_MSG_SERVICE_ACCEPT received
debug3: send packet: type 50
debug3: receive packet: type 51
debug1: Authentications that can continue: publickey
debug3: start over, passed a different list publickey
debug3: preferred gssapi-with-mic,gssapi-keyex,hostbased,publickey
debug3: authmethod_lookup publickey
debug3: remaining preferred: ,gssapi-keyex,hostbased,publickey
debug3: authmethod_is_enabled publickey
debug1: Next authentication method: publickey
debug1: Offering RSA public key: /home/redacted/.ssh/id_rsa
debug3: send_pubkey_test
debug3: send packet: type 50
debug2: we sent a publickey packet, wait for reply
debug3: receive packet: type 51
debug1: Authentications that can continue: publickey
debug1: Offering RSA public key: key2
debug3: send_pubkey_test
debug3: send packet: type 50
debug2: we sent a publickey packet, wait for reply
debug3: receive packet: type 51
It then continues to try the remaining keys I have in my .ssh
directory, which all fail, of course. The first one, the one that was requested, has already failed.
I ran Packer with -on-error=abort
so that it would leave the VM up. I tried SSHing in with the same command, and I get a connection refused error. The reason for this, I discovered, is that it's trying to connect to an SSH proxy port that Packer sets up. So I use the actual forwarded port that is set up on the Virtualbox VM, and SSH connection succeeds. Thus, it appears that the problem lies with the SSH proxy. However, I'm not sure how to make it behave.
I also tried using the ssh_authorized_key_file
option (https://www.packer.io/docs/provisioners/ansible.html) in my Packer configuration for the Ansible provisioner. In this case, I got a Packer error saying that it failed to parse the authorized key (source code is here: https://github.com/bhcleek/packer-provisioner-ansible/blob/master/provisioner/ansible/provisioner.go). It didn't tell me what the problem is. The Go documentation for the SSH library said that it's the standard SSH keyfile format. Or that's my best interpretation of it (https://godoc.org/golang.org/x/crypto/ssh#ParseAuthorizedKey).