16

Is there anyway that I can ssh into a guest vm through virsh instead of find the ip address of the guest vm?

e.g.

what I want is ssh into a guest like this way :

$virsh ssh_or_somwthing <domain>

but not like this:

$ #1) find the guest vm's IP address:
$arp
...
$ #2) ssh someone@<IP>
gansteed
  • 161

4 Answers4

9

Jacek has the right answer, but just to lay out some of the specifics:

  1. Log into the VM using the KVM GUI
  2. On the VM command line, type in:

    systemctl enable serial-getty@ttyS0.service
    systemctl start serial-getty@ttyS0.service
    

You will be asked multiple times to enter your password/accept.

  1. Reboot the VM
  2. Then, from the terminal on your main machine, type in:

    sudo virsh console your_vm_name_here
    

Obviously replacing "your_vm_name_here" with whatever the VM name is.

Then you can "ssh" directly into the VM using virsh.

  • 7
    This allows you to access the VM via a terminal, but this has nothing to do with SSH. – Jounathaen Dec 28 '19 at 17:37
  • error: internal error: character device console0 is not using a PTY – Dave Ankin Jun 20 '22 at 08:12
  • Can anyone know how to access the console without a password but a private key? I mainly ssh into the VM with PK, but via virsh console I had to provide the password, which I am totally unaware of. – s3cret Aug 09 '23 at 01:52
1

I'm not sure about it, but I think you're looking to configure console access to the guest? It may not be the only solution (not following virsh very actively and all this stuff) - but you can setup serial console on your guest, configure your supervisor and then use virsh console domain.

Anyway - have a look at this: https://help.ubuntu.com/community/KVM/Access - I guess it may help or at least put you in some direction.

Jacek
  • 1,911
  • 12
  • 10
0

You may want to take a read of SSHsetup for libvirtd

https://wiki.libvirt.org/page/SSHSetup

Seems to do what you want.

  • 2
    The link you provided shows how to set up ssh communications to libvirt running on another system. This uses ssh just as a tunnel between virsh (or virt-manager) and libvirt on different machines. The OP is looking to send console commands directly through virsh to the VM, using virsh as a proxy or tunnel into the VM, rather than via ssh to the VM itself. This would be useful for running a VM with no networking, but still have effectively a serial console into the VM. – mainmachine Sep 09 '21 at 18:50
0

virsh itself does not supply ssh capabilities in managing the VMs*.

If we want to access the machine through ssh, we may only do that through the ssh command.

Following are the 2 steps for that.

1. Setting Up the SSH Access

For the first step there are 2 tracks

Pre-Configure the Machine (eg: Cloud-Init)

We could use cloud-init (may be also preseed.cfg/kickstart ... etc.) to install the public key.

# Cloud-init snippet
users:
  - name: your_username
    ssh-authorized-keys:
      - your_public_ssh_key

Manual Configuration

  1. Ensure that ssh daemon is running in the VM, if you have an interactive access, you could run virsh console $vm_name then set up the ssh daemon. If there's no interactive access you'll need to use any of the following:

    • virt-customize while the machine is shut off virt-customize -d "$vm_name" --run-command "command to install ssh"
      or
    • expect to send keystrokes to setup the VM, which could be found in the appendix of this answer.
      or
    • any other tool that sends keystrokes to the VM
  2. Install your public key into the VM:

    # virt-copy-in requires the virtual machine to be stopped
    #   for example this should return `shut off`
    virsh dominfo my_vm | grep State | awk -F':' '{print $2}' | sed 's/^[[:space:]]*//; s/[[:space:]]*$//'
    # virt-copy-in takes a file argument and a directory argument
    # thus we need to use a correct filename before copying
    if [ ! -f ~/.ssh/id_rsa ]; then
        ssh-keygen -t rsa -N "" -f ~/.ssh/id_rsa
    fi
    cp ~/.ssh/id_rsa.pub /tmp/authorized_keys
    # Finally, virt-copy-in may require sudo
    virt-copy-in -d "$vm_name" /tmp/authorized_keys /home/ubuntu/.ssh/
    

2. Accessing the VM

  1. Capture the IP address:
    export vm_ip_address=$(virsh domifaddr my_vm | awk '/ipv4/ {print $4}' | awk -F'/' '{print $1}')
    
  2. ssh into the machine
    export vm_user=ubuntu # set the correct username here
    ssh $vm_user@$vm_ip_address
    

* virsh could use ssh to communicate with remote servers, but that has nothing to do with accessing the virtual machines themselves.

Appendix

Following is an expect snippet that could be used to automate setting up the interactive console access in a non-interactive manner.

#!/usr/bin/expect -f

Function to wait for a specific string before sending the command

proc wait_for_prompt { } { expect "# " ; # Modify the expected prompt if needed }

Function to send a command and wait for the output

proc send_command { command } { send "$command\r" expect "# " ; # Modify the expected prompt if needed }

Replace 'vm_name' with the actual name of your virtual machine

set vm_name "my_vm"

Replace 'your_command' with the command you want to run inside the VM

set command_to_run1 "sudo apt-get install openssh-server." set command_to_run2 "sudo systemctl start ssh" set command_to_run3 "sudo systemctl enable ssh"

#spawn virsh start $vm_name

Spawn the virsh command

spawn virsh

Wait for the virsh prompt

expect "virsh # "

Start the virtual machine

send "start $vm_name\r"

send "console $vm_name\r"

Wait for the console to start

Send double enters

send_command "" send_command "" expect -timeout 100 "ubuntu login"

Set password

send_command "ubuntu" send_command "ubuntu"

we may need to login again if prompted

send_command "ubuntu" send_command "ubuntu"

run the commands

send_command "$command_to_run1" send_command "$command_to_run2" send_command "$command_to_run3"

Wait for the output of the command to appear

expect "your_expected_output" ; # Modify this line to match the expected output

Exit the console

send "\x1d" expect eof

weshouman
  • 103