67

How do I setup ssh from the host to the guest using qemu? I am able to use port redirection when I boot the VM without any special parameters, as follows:

/usr/bin/qemu-system-x86_64 -hda ubuntu1204 -m 512 -redir tcp:7777::8001

But when I try to boot using the following:

/usr/bin/qemu-system-x86_64 \
-m 1024 \
-name vserialtest \
-hda ubuntu1204 \
-chardev socket,host=localhost,port=7777,server,nowait,id=port1-char \
-device virtio-serial \
-device virtserialport,id=port1,chardev=port1-char,name=org.fedoraproject.port.0 \
-net user,hostfwd=tcp:7777::8001

I get the following error and the VM does not boot:

qemu-system-x86_64: -net user,hostfwd=tcp:7777::8001: invalid host
forwarding rule 'tcp:7777::8001'
qemu-system-x86_64: -net user,hostfwd=tcp:7777::8001: Device 'user'
could not be initialized

Please note that I am able to boot the VM without the -net parameter without any issues, however, I want to setup ssh from the host to the guest. ssh from guest to host works fine as expected.

Edit

I have tried using

-net user,hostfwd=tcp::7777-:8001

as well as

-net user,hostfwd=tcp::7777:8001

but still the error persists and the VM does not boot.

Ciro Santilli OurBigBook.com
  • 18,092
  • 4
  • 117
  • 102
jobin
  • 886

5 Answers5

68

I think that the error does not come from the -net statement, but from:

-chardev socket,host=localhost,port=7777,server,nowait,id=port1-char

The statement uses already the port 7777. For the port forwarding, with

-net user,hostfwd=tcp::7777-:8001

It works fine when not setting up the virtio serial channel.

If I understand right, you want to set up a virtio serial channel to communicate from the host to the VM using a Unix Domain Socket?

In this case, the following could do the job:

/usr/bin/qemu-system-x86_64 \
-m 1024 \
-name vserialtest \
-hda ubuntu1204 \
-chardev socket,path=/tmp/port1,server=on,wait=off,id=port1-char \
-device virtio-serial \
-device virtserialport,id=port1,chardev=port1-char,name=org.fedoraproject.port.0 \
-net user,hostfwd=tcp::7777-:8001

An example of how to connect from the host using ssh to the VM:

-net user,hostfwd=tcp::10022-:22
-net nic

This host-forwarding maps the localhost (host) port 10022 to the port 22 on the VM. Once the VM was started like this, you can access it from the localhost as follows:

ssh vmuser@localhost -p10022

The -net nic command initializes a very basic virtual network interface card.

Elazar
  • 103
  • 4
mas_kur1
  • 804
  • Yes, you are right, I am trying to use virtio-serial to establish communication from host to guest. The VM has booted giving a warning at the host console: Warning: vlan 0 with no nics but when I do ifconfig on the guest I see only lo and I still get ssh: connect to host 10.0.2.15 port 22: Connection timed out when I try to ssh; the IP I used to ssh is 10.0.2.15, which according to man qemu-system-x86_64 is the IP assigned to the first VM booted if static IP is not assigned. And now there is no internet connection on the guest. – jobin Apr 15 '14 at 08:06
  • What you might want to do is to map the port 22 used for ssh on another port and then connect to it from the host machine to access the VM. I edited my answer with an example. – mas_kur1 Apr 15 '14 at 13:23
  • The edited answer works perfectly! – dbernard Oct 11 '19 at 20:35
  • 5
    It can be shortened on recent qemu versions with "-nic user,hostfwd=tcp::10022-:22" without the second "-net nic" – wuxb May 09 '20 at 21:46
  • You saved my life dude! – Smeterlink Sep 12 '21 at 04:45
34

Add this to your qemu network config:

,hostfwd=tcp::2222-:22

e.g.

qemu -net nic -net user,hostfwd=tcp::2222-:22

The tcp::2222-:22 flag maps port 2222 of the host machine to port 22 (the default SSH port) on the virtual machine.

Then, simply SSHing to port 2222 on your localhost (the host machine) will redirect any traffic into the SSH port in the virtual machine, which should allow you to ssh as you normally would any other machine:

$ ssh -p 2222 localhost
Wilduck
  • 7,577
  • 5
    Welcome to Unix&Linux!  We’re looking for long answers that provide some explanation and context.  Don’t just say "Try this ..."; explain why your answer is right, ideally with citations.  Answers that don’t include explanations may be removed. – G-Man Says 'Reinstate Monica' Apr 14 '15 at 05:22
  • 5
    I just feel the need to say that this answer helped me more than all the other answers above. No superfluous information and above all, it works. Perfect when landing from a google-query "how the heck do I ssh into qemu". – jan Apr 15 '15 at 13:14
  • 2
    This answer does what 99.9% of people actually want. I.e. host machine gets ssh access to virtual machine, including the ability for the host to copy files to and from the virtual machine using scp or similar. – nullUser May 25 '15 at 15:13
  • 1
    Brilliant! My Raspberry Pi command now looks like qemu-system-arm -kernel kernel-qemu -cpu arm1176 -m 256 -M versatilepb -no-reboot -append "root=/dev/sda2 panic=1 rootfstype=ext4 rw console=ttyAMA0,115200" -hda 2014-01-07-wheezy-raspbian.img -nographic -redir tcp:2222::22 – enthusiasticgeek Aug 24 '16 at 01:20
  • 2
    man qemu-system-x86_64 2.5.0: Note: Legacy stand-alone options -tftp, -bootp, -smb and -redir are still processed and applied to -net user. – Ciro Santilli OurBigBook.com Sep 02 '16 at 21:19
  • this is deprecated, but works great still ATM – FreeSoftwareServers Jan 28 '18 at 06:09
  • 3
    Based on the accepted answer, I guess the non-deprecated equivalent is: qemu -net nic -net user,hostfwd=tcp::2222-:22 – mwfearnley Feb 03 '18 at 12:45
  • 2
    qemu-system-x86_64: -redir: invalid option – Aaron Franke May 05 '21 at 06:32
  • Adding ,hostfwd=tcp::2222-:22 to my network config worked for me. – Aaron Franke Aug 28 '21 at 17:20
  • Is this an argument of starting the VM, or you have a qemu command that does system-wide config? – minseong May 03 '23 at 19:54
11

OpenSSH configuration tested on Buildroot 2016.05, QEMU 2.5.0, Ubuntu 16.04 host

Besides the QEMU network forwarding, you also need to setup SSH properly, which I'll cover here.

Start with qemu_x86_64_defconfig and enable the openssh package:

make qemu_x86_64_defconfig
echo 'BR2_PACKAGE_OPENSSH=y' >> .config
make BR2_JLEVEL=$(nproc)

Then start QEMU with:

qemu-system-x86_64 \
  -M pc \
  -append root=/dev/vda \
  -drive file=output/images/rootfs.ext2,if=virtio,format=raw \
  -enable-kvm \
  -kernel output/images/bzImage \
  -m 512 \
  -net nic,model=virtio \
  -net user,hostfwd=tcp::2222-:22

Then on guest:

vi /etc/ssh/sshd_config

Modify the following settings:

PermitRootLogin yes
PermitEmptyPasswords yes

And restart the server:

/etc/init.d/S50sshd restart

It is because this file exists that sshd starts by default, here is the source: https://github.com/buildroot/buildroot/blob/2018.02/package/openssh/S50sshd and the key startup operations are:

/usr/bin/ssh-keygen -A
/usr/sbin/sshd
touch /var/lock/sshd

Then from host:

ssh root@localhost -p 2222

In case of failure, first test that the networking forwarding is working with a lower level tool than sshd: e.g. nc -l as described here.

also check the server logs on guest:

less /var/log/messages

Then on the final system you should automate the creation of that log file with BR2_ROOTFS_OVERLAY or BR2_ROOTFS_POST_BUILD_SCRIPT: Customizing the generated target filesystem | buildroot.org

Related: https://stackoverflow.com/questions/23106012/how-to-access-raspberry-pi-qemu-vm-via-network

Ciro Santilli OurBigBook.com
  • 18,092
  • 4
  • 117
  • 102
4

Answers here all seem somewhat out of date or overly specific to the poster's exact situation. In general you can enable ssh by adding this to your qemu command:

-device e1000,netdev=net0 -netdev user,id=net0,hostfwd=tcp::5555-:22

Then once it's up and running (make sure you have openssh-server installed on guest), you can ssh in from the host with:

ssh guestUserName@localhost -p 5555

See here under "How to get SSH access to a guest" for more details

Danny
  • 141
-1

I believe you need to use hostfwd=tcp::7777-:8001 or hostfwd=tcp::7777:8001

ek9
  • 2,905