-
Notifications
You must be signed in to change notification settings - Fork 463
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Connection to libvirt via SSH fails with provider version 0.6.9 #864
Comments
I ran into similar issues yesterday. You can (temporarily?) specify the location of the private as a query parameter in the connection URI. Assuming you are using the default filename for an ed25519 key, your URI would become something like this.
|
@pmaene Thanks for the workaround, you guessed the filename correctly, unfortunately I get another error: My best guess is that it's because my key has a passphrase set, but terraform isn't asking for it, instead it just fails. I can maybe try to test it later with a temporary ed25519 key without a passphrase. Is your key having a passphrase set? |
You're right that this error has to do with the fact that your key has a passphrase set. Using a temporary key without one set should allow you to continue. |
Can the golang SSH client not use the SSH agent? SSH keys without passphrases are a bad idea, and generating a temporary one just to run Terraform makes for an unpleasant user experience. |
I don't necessarily agree that keys without a passphrase are always a bad idea (see for instance this tweet). However, I was also thinking that adding SSH agent support would resolve both the private key discovery and passphrase issues. Go's |
@pmaene that particular tweet only applies to situations where the SSH keys don't give you access anywhere interesting :-) I regularly use systems (including my current desktop, mostly) where I wouldn't care much about the contents of my home directory leaking except for the SSH keys because they give access to the places where all the interesting data is stored. To get back on topic, you can also work around this by using netcat manually. First run something like this: |
@oranenj As with anything security-related, it always depends on your attacker model Thanks for the netcat-based workaround, that's a great tip. |
When I got rid of the libvirt client library, I had to write the ssh transport from scratch. I followed the documentation. I don't think I implemented the |
@dmacvicar Looking at the documentation for the ssh library, it doesn't seem too difficult to add support for specifying SSH auth methods so I might take a stab at it if you didn't already get to it. |
Give it a try. Everything is in the libvirt/uri subdirectory, with one file per transport. Only thing I'd like to keep in mind is to be as close as possible in behavior to the C libvirt client. |
Seeing this on Fedora 34 with 0.6.10. |
I'm also seeing similar behavior on MacOS 11.5. My URI Connection string is That connection string works with Here is the Terraform Output
WorkAroundI forwarded the unix port using SSH.
Here is the script I use. #!/usr/bin/env bash
set -xe
cleanup() {
for pid in $(pgrep ssh \-fnNT); do kill -3 "$pid"; done
rm $1
}
libvirt_sock="$TMPDIR/libvirt-sock"
ssh -fnNT -L "$libvirt_sock":/var/run/libvirt/libvirt-sock -i ~/.ssh/id_ed25519 [email protected]
trap "cleanup $libvirt_sock" ERR EXIT
export LIBVIRT_DEFAULT_URI="qemu+unix:///session?socket=$libvirt_sock"
#Verify Connection
virsh -c "$LIBVIRT_DEFAULT_URI" sysinfo >/dev/null
#Use terraform
for cmd in init plan apply; do
terraform "$cmd"
done
trap "terraform destroy" EXIT ERR
echo "Press Return to Quit & Cleanup..."
read |
Hello. Here is my tf configuration terraform {
required_version = "1.0.4"
backend "http" {
address = "https://gitlab.com/api/v4/projects/PROJECT_ID/terraform/state/dedibox-1"
lock_address="https://gitlab.com/api/v4/projects/PROJECT_ID/terraform/state/dedibox-1/lock"
unlock_address="https://gitlab.com/api/v4/projects/PROJECT_ID/terraform/state/dedibox-1/lock"
username="putchar"
password="MYPASS"
lock_method="POST"
unlock_method="DELETE"
retry_wait_min="5"
}
required_providers {
libvirt = {
source = "dmacvicar/libvirt"
version = "0.6.10"
}
}
}
provider "libvirt" {
uri = "qemu+ssh://putchar@dedibox-1/system"
}
resource "libvirt_domain" "terraform_test" {
name = "terraform_test"
} and this is what i see
my ssh key has no passphrase and i can ssh properly on the remote-host |
I see this: provider "libvirt" { terraform { ❯ terraform init Initializing the backend... Initializing provider plugins...
Partner and community providers are signed by their developers. Terraform has made some changes to the provider dependency selections recorded Terraform has been successfully initialized! You may now begin working with Terraform. Try running "terraform plan" to see If you ever set or change modules or backend configuration for Terraform, ❯ terraform plan Error: failed to dial libvirt: ssh: handshake failed: ssh: unable to authenticate, attempted methods [none publickey], no supported methods remain on main.tf line 1, in provider "libvirt": older version works correctly, can also ssh into the 'kvm' machine with private key, because that is specified in the ssh config |
Dear Duncan <@dmacvicar>
A lot of the connection functionality, especially ssh, worked nicely prior this design change. Why did you make the decision to drop the dependency to the libvirt library? Is there anything that can make you consider the use of the libvirt library again? Personally I prefer the use of the libvirt client and not to implement the libvirt protocol and the ssh protocol all by myself. The software would have to be kept always compatible, the efforts of maintenance would be high. Client libraries like the libvirt or ssh libraries are explicitly created from the other projects, so I don't have to think about the protocol and can stay compatible over multiple versions. Hoping for the best and thank you for creating this wonderful piece of software, which I use everyday ❤️ |
Because we needed a pure Go provider in order to be able to distribute using the Hashicorp Provider Registry which means people can install it just mentioning the provider. Distributing a binary linking to a C library meant we have to provide different binaries per distribution. |
I could not find a policy or rule made by Hashicorp, that would reject providers with external dependencies. But there is a statement about the compatibility towards Terraform Cloud here: https://www.terraform.io/docs/registry/providers/os-arch.html#terraform-cloud-compatibility Citing:
Hashicorp is stating that a provider should not have external dependencies, because it can not guarantee those dependencies available on Terraform cloud. Hashicorp is not stating all provider must not have external dependencies in general.
From my knowledge, in C there is the possibility instead to link to a library to dynamically load the library on runtime. The libvirt library is available as [root@voyager ~]# ldconfig -p|grep -i libvirt|grep 'libvirt.so '
libvirt.so (libc6,x86-64) => /usr/lib64/libvirt.so Putting those two information together, we can conclude, that a Hashicorp provider could dynamically load libvirt, if it is availble on the system, instead of linking to it. If it is not available it could fallback to a functionality limited builtin. @dmacvicar, could it be a compromise of functionality and efforts to offer one provider that has full functionality for the non Terraform Cloud scenario and a limited builtin functionally for the Terraform Cloud scenario? PS.: Or having two providers, one dynamically linked |
I am not sure what you are suggesting. When we linked against libvirt, we used the official bindings https://github.com/libvirt/libvirt-go which require CGO and therefore can't be used in the Terraform registry. Maintaining a different set of bindings is considerable effort (and I am not even sure if it is technically possible). The only reason why we can rely on a different approach is because we have alternative bindings, maintained outside the scope of this project. Now, that does not mean we will ignore these feature gaps. I will try to fix them, inside our limited capacity of few developers and many users. |
This is fixed and will be part of 0.6.11. Thanks @oranenj for contributing the fix. I tested locally using encrypted ed25519 keys and the GNOME ssh agent. |
After reading your last comment @dmacvicar I've realized that
Versions:
Now I'm extremely happy deploying remotely my virtual machines :) |
Hello, I'm hesitant to open a new issue without asking for help here in this thread. I was using v0.6.10 and the connection string below was working just fine:
Now with 0.6.11 it is failing with message:
I've removed the keyfile part but it is still failing. If I ssh to the host it works just fine. Any ideas? Thanks |
Is your key encrypted with password? If yes, you need a ssh agent. |
@mariogarcia what is the error with RSA keys? |
@dmacvicar : No, my key does not have a password. It was working just fine with 0.6.10. |
@dmacvicar these are the steps I followed to reproduce it Generate ssh RSA keymylocalsystem:~$ ssh-keygen -t rsa -b 4096 -C "[email protected]"
Generating public/private rsa key pair.
Enter file in which to save the key (/home/myuser/.ssh/id_rsa): /home/myuser/.ssh/id_rsa_todelete
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /home/myuser/.ssh/id_rsa_todelete
Your public key has been saved in /home/myuser/.ssh/id_rsa_todelete.pub
The key fingerprint is:
SHA256:1ayb5UmYFecSw0grNidiBR1XH382QqhyU1bq9KkMeIM [email protected]
The key's randomart image is:
+---[RSA 4096]----+
| .oooo+Boo |
| ....B+B o |
| o = Bo=.o.+|
| . +oXo=..o.o|
| ES+=.oo |
| . +*.. |
| ooo |
| |
| |
+----[SHA256]-----+ Copied public key to remote KVM serverChanging ~/.ssh/config file in localHost mykvmserver
HostName 192.168.1.35
User maestro
IdentityFile ~/.ssh/id_rsa_to_delete Executing terraform and getting the errorterraform apply And the error 2021-09-17T12:35:49.501+0200 [INFO] Terraform version: 1.0.6
2021-09-17T12:35:49.501+0200 [INFO] Go runtime version: go1.16.4
2021-09-17T12:35:49.501+0200 [INFO] CLI args: []string{"/home/myuser/.bin/terraform", "apply"}
...
2021-09-17T12:35:50.057+0200 [DEBUG] provider: starting plugin: path=.terraform/providers/registry.terraform.io/dmacvicar/libvirt/0.6.11/linux_amd64/terraform-provider-libvirt_v0.6.11 args=[.terraform/providers/registry.terraform.io/dmacvicar/libvirt/0.6.11/linux_amd64/terraform-provider-libvirt_v0.6.11]
2021-09-17T12:35:50.057+0200 [DEBUG] provider: plugin started: path=.terraform/providers/registry.terraform.io/dmacvicar/libvirt/0.6.11/linux_amd64/terraform-provider-libvirt_v0.6.11 pid=10153
2021-09-17T12:35:50.057+0200 [DEBUG] provider: waiting for RPC address: path=.terraform/providers/registry.terraform.io/dmacvicar/libvirt/0.6.11/linux_amd64/terraform-provider-libvirt_v0.6.11
2021-09-17T12:35:50.062+0200 [INFO] provider.terraform-provider-libvirt_v0.6.11: configuring server automatic mTLS: timestamp=2021-09-17T12:35:50.062+0200
2021-09-17T12:35:50.087+0200 [DEBUG] provider.terraform-provider-libvirt_v0.6.11: plugin address: address=/tmp/plugin182159544 network=unix timestamp=2021-09-17T12:35:50.087+0200
2021-09-17T12:35:50.087+0200 [DEBUG] provider: using plugin: version=5
2021-09-17T12:35:50.120+0200 [DEBUG] provider.stdio: received EOF, stopping recv loop: err="rpc error: code = Unimplemented desc = unknown service plugin.GRPCStdio"
2021-09-17T12:35:50.120+0200 [INFO] ReferenceTransformer: reference not found: "var.cloudinit_net_conf"
2021-09-17T12:35:50.120+0200 [DEBUG] ReferenceTransformer: "module.hadoop-metis.data.template_file.network_config" references: []
2021-09-17T12:35:50.120+0200 [INFO] ReferenceTransformer: reference not found: "var.cloudinit_user_conf"
2021-09-17T12:35:50.120+0200 [INFO] ReferenceTransformer: reference not found: "var.ssh_public_key_path"
2021-09-17T12:35:50.120+0200 [DEBUG] ReferenceTransformer: "module.hadoop-jupyter.data.template_file.user_data" references: []
2021-09-17T12:35:50.120+0200 [DEBUG] No provider meta schema returned
2021-09-17T12:35:50.121+0200 [INFO] ReferenceTransformer: reference not found: "var.cloudinit_net_conf"
2021-09-17T12:35:50.121+0200 [DEBUG] ReferenceTransformer: "module.hadoop-adrastea.data.template_file.network_config" references: []
2021-09-17T12:35:50.121+0200 [INFO] ReferenceTransformer: reference not found: "var.cloudinit_net_conf"
2021-09-17T12:35:50.121+0200 [DEBUG] ReferenceTransformer: "module.hadoop-io.data.template_file.network_config" references: []
2021-09-17T12:35:50.122+0200 [INFO] ReferenceTransformer: reference not found: "var.cloudinit_user_conf"
2021-09-17T12:35:50.122+0200 [INFO] ReferenceTransformer: reference not found: "var.ssh_public_key_path"
2021-09-17T12:35:50.122+0200 [DEBUG] ReferenceTransformer: "module.hadoop-metis.data.template_file.user_data" references: []
2021-09-17T12:35:50.122+0200 [INFO] ReferenceTransformer: reference not found: "var.cloudinit_user_conf"
2021-09-17T12:35:50.122+0200 [INFO] ReferenceTransformer: reference not found: "var.ssh_public_key_path"
2021-09-17T12:35:50.122+0200 [DEBUG] ReferenceTransformer: "module.hadoop-io.data.template_file.user_data" references: []
2021-09-17T12:35:50.122+0200 [INFO] ReferenceTransformer: reference not found: "var.cloudinit_net_conf"
2021-09-17T12:35:50.122+0200 [DEBUG] ReferenceTransformer: "module.hadoop-jupyter.data.template_file.network_config" references: []
2021-09-17T12:35:50.123+0200 [INFO] ReferenceTransformer: reference not found: "var.cloudinit_user_conf"
2021-09-17T12:35:50.123+0200 [INFO] ReferenceTransformer: reference not found: "var.ssh_public_key_path"
2021-09-17T12:35:50.123+0200 [DEBUG] ReferenceTransformer: "module.hadoop-adrastea.data.template_file.user_data" references: []
2021-09-17T12:35:50.124+0200 [DEBUG] provider.terraform-provider-libvirt_v0.6.11: 2021/09/17 12:35:50 [DEBUG] Configuring provider for 'qemu+ssh://maestro@mykvmserver/system': &{map[uri:0xc00015e3c0] <nil> <nil> 0xc000146260 map[] <nil> 0xc0001462e0 0xc00012e498 0xc000150410 false map[] {1 {0 0}} false false}
2021-09-17T12:35:50.126+0200 [DEBUG] provider: plugin process exited: path=.terraform/providers/registry.terraform.io/hashicorp/template/2.2.0/linux_amd64/terraform-provider-template_v2.2.0_x4 pid=10140
2021-09-17T12:35:50.126+0200 [DEBUG] provider: plugin exited
╷
│ Error: failed to dial libvirt: ssh: handshake failed: EOF
│
│ with provider["registry.terraform.io/dmacvicar/libvirt"],
│ on main.tf line 10, in provider "libvirt":
│ 10: provider "libvirt" { Now changing to an ed25519 key
When it's working it seems that the call is the same, I didn't see anything that could make the difference. In the success case once it does the call it keeps going. ...
2021-09-17T12:49:26.080+0200 [DEBUG] No provider meta schema returned
2021-09-17T12:49:26.081+0200 [DEBUG] provider.terraform-provider-libvirt_v0.6.11: 2021/09/17 12:49:26 [DEBUG] Configuring provider for 'qemu+ssh://maestro@mykvmserver/system': &{map[uri:0xc0005163c0] <nil> <nil> 0xc0005580c0 map[] <nil> 0xc000558140 0xc000502210 0xc0005c4280 false map[] {1 {0 0}} false false}
... I hope it helps |
@mariogarcia can you somehow get the list of ciphers supported by your server?
(run on the server) or
remotely I want to compare those with https://github.com/golang/crypto/blob/master/ssh/cipher.go#L99 |
@dmacvicar here you have it:
More information that could be relevant about the server:
|
Same here. Replicated on server with OpenSSH_8.8p1, OpenSSL 1.1.1l 24 Aug 2021 |
Possibly related:
|
@jli-cparta @frgomes I continue to try to reproduce this without success. Lets continue in #886 886 |
Setting this on server-side ssh config fixed it for me:
|
… have a bug which can prevent SSH-based libvirt connections: dmacvicar/terraform-provider-libvirt#864
Works with this config:
in provider config I use: (i use ssh agent so i just put user@host ) I think if you specify ssh private key, it will also work. |
… have a bug which can prevent SSH-based libvirt connections: dmacvicar/terraform-provider-libvirt#864
System Information
Linux distribution
Fedora 34
Terraform version
Provider and libvirt versions
Checklist
Is your issue/contribution related with enabling some setting/option exposed by libvirt that the plugin does not yet support, or requires changing/extending the provider terraform schema?
Is it a bug or something that does not work as expected? Please make sure you fill the version information below:
Description of Issue/Question
Connecting to a remote libvirt provider via SSH fails after updating to v0.6.9 with the error message
Error: failed to dial libvirt: failed to read ssh key: open /home/soeren/.ssh/id_rsa: no such file or directory
. I'm indeed not using RSA keypairs anymore, instead I've been using ed25519 keypairs. Reverting back to v0.6.3 of the provider makes it work again. For the given remote host there's no additional settings in the local ~/.ssh/config file.Setup
Steps to Reproduce Issue
...after changing the provider version to 0.6.3 again
Additional information:
SELinux is enabled on the host running the terraform code, however, disabling SELinux doesn't fix the issue.
The text was updated successfully, but these errors were encountered: