Ssh/sign fails with "failed to parse public_key as SSH key: illegal base64 data at input byte 0"

I’m trying to get SSH host signing working with Vault and Consul-Template. The template file for Consul-Template looks like:

{{ $contents := file "/etc/ssh/ssh_host_rsa_key.pub" }}{{ with secret "ssh-host/sign/ssh.host.linux" "cert_type=host" "public_key=$contents" }}{{ .Data.signed_key }}{{ end }}

The SSH public key file looks like (note this is an example key for a test VM):

ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDxE3HPu3ZejCJyhYM/da0jIlTKjVlsXEczaiUOrrrr9QPi0InCuU3tZEBSxZ5Xa6bG0iNb/FNEhhPztxgmD9hM7h+54r7fWbW4Zbk3HJFfWeym+EnAzmDx28ImY07XKlTrCok/qV9SrLm+cjt459wzJSAUsTBS2t+D2OnFlVPoM0NKorgO9tepHpMWL9ylG4Xt3M8NtxE0kZksVVv8iuynEeLdzogQbVc+rIU+Xomw5NUxmENJ/8pGFa3WsZnxdbmURlXzCoHAUwLO3Rd1C8LElBNh963mMF1mSx99WqkVDmiaVamtnqRjU3e/YYrr1T9NzT4yGywKiasTUKooTFi9 root@ubuntu-18-04-3

When Consul-Template tries to execute the template it fails with:

(view) vault.write(ssh-host/sign/ssh.host.linux -> 564133f1): vault.write(ssh-host/sign/ssh.host.linux -> 564133f1):
URL: PUT http://active.secrets.service.integrationtest:8200/v1/ssh-host/sign/ssh.host.linux
Code: 400. Errors:
* failed to parse public_key as SSH key: illegal base64 data at input byte 0 (retry attempt 3 after "1s")

Looking at the Vault code for parsing the key it looks like Vault is smart enough to throw away the first and last bit of the key file and only use the middle bit.

The key was automatically generated (?) when the VM was first started (I think it works that way, I didn’t manually generate it and as far as I can tell the key was there the first time I connected).

I would have expected the key to be generated in the correct format but it is well possible that there is a setting somewhere that I have missed.

Does anybody know what configuration / conversions I have missed to make this work?

It turns out that the error was due to the fact that my template was wrong. It should have been

{{ $contents := file "/etc/ssh/ssh_host_rsa_key.pub" | trimSpace }}{{ $pair := printf "public_key=%s" $contents }}{{ with secret "ssh-host/sign/ssh.host.linux" "cert_type=host" $pair }}{{ .Data.signed_key }}{{ end }}

Apparently Consul-Template cannot / does not process variables inside quotes, however if you create a variable that contains the key-value pair and pass that to the secret function it will work.

2 Likes

I am also stuck at same error. But its not in consul. Its plain vault write

vault write -field=signed_key ssh-user-ca/sign/ssh-test public_key=B_mac.pub valid_principals=“vadmin” > B_mac_cert.pub
Error writing data to ssh-user-ca/sign/ssh-test: Error making API request.

URL: PUT http://127.0.0.1:8200/v1/ssh-user-ca/sign/ssh-test
Code: 400. Errors:

*** failed to parse public_key as SSH key: illegal base64 data at input byte 1**

You sent the literal string

to Vault as your SSH key. Of course, that’s not a valid SSH key.

Re-check the docs - you need a leading @ sign to tell the Vault CLI to read a file and substitute it’s contents as a parameter.

You’re lifesaver! Stuck into this problem also and this only thread along the Google helped me.