Port Forwarding between host-guest via passt using QEMU-libvirt
Hi All, I'm having trouble getting host-to-guest port forwarding to work via passt for a userspace connection: Please see my post on Superuser for more details: https://superuser.com/q/1927306/3115375?sem=2 Thank you. Best, James
On Sun, Oct 26, 2025 at 02:47:19PM -0500, James Sinton wrote:
Hi All,
I'm having trouble getting host-to-guest port forwarding to work via passt for a userspace connection:
Please see my post on Superuser for more details:
Sorry it's taken me a while to look at this. It looks like passt is accepting the ssh connection, but unable to itself connect to the guest. Unfortunately there aren't really any clues as to why, so far. A couple of easy bits of information which might help: 1. What's the passt version? (`passt --version` on the host) 2. What's the IP configuration within the Windows guest? 3. What's the IP configuration on the host? (`ip addr show` and `ip route show`) 4. What's the output from `ssh -v` That information might supply some clues, but it's pretty likely we'll need debugging or packet capture output from passt to work this out. Unfortunately, that's a bit trickier than it should be because libvirt doesn't (yet) have the ability to pass the necessary options to passt. Let's start with the information above, then we can work out the steps to get more detailed debugging information if we need it. -- David Gibson (he or they) | I'll have my music baroque, and my code david AT gibson.dropbear.id.au | minimalist, thank you, not the other way | around. http://www.ozlabs.org/~dgibson
Hi David,
Thank you for getting back to me. I have been trying to rehash some of the
Arch documentation (https://wiki.archlinux.org/title/Libvirt), and I worked
through parts of this tutorial for WinApps as another resource for
configuring libvirt to run a Windows guest on a Linux host:
https://github.com/winapps-org/winapps/blob/main/docs/libvirt.md
I think I found that the services for the libvirt daemon were not enabled.
I also double checked that the user on the host has been added to the
libvirt group.
One tidbit is that the host is connected to the internet via WiFi (wlp6s0),
hence, the motivation to use passt in userspace mode.
A couple of easy bits of information which might help:
1. What's the passt version? (`passt --version` on the host)
passt 2025_09_11.6cbcccc
2. What's the IP configuration within the Windows guest?
The windows guest:
Aggregated link speed (Receive/Transmit): 10/10 (Gbps)
IPv6 address: fdac:14bf:9c6f:942d:d4:e913:5731:9d0a
Link-local IPv6 address: fe80::5374:1174:7d88:4c94%12
IPv6 default gateway: fe80::11a9:af53:4e56:ea79%12
IPv4 address: 10.0.1.205
IPv4 DNS servers: 10.0.1.1 (Unencrypted)
8.8.8.8 (Unencrypted)
Manufacturer: Red Hat, Inc.
Description: Red Hat VirtIO Ethernet Adapter
Driver version: 100.101.104.28500
Physical address (MAC): 52:54:00:23:01:04
Notice that it matches wlp6s0 below due to the userspace mode config.
3. What's the IP configuration on the host? (`ip addr show` and `ip route
show`)
FYI, I have some docker containers running on the host as well. virbr0 is
part of the virsh net. But in userspace mode with port forwarding, I
shouldn't need an active bridge network for host-guest communication,
correct?
$ ip addr show
1: lo:
Hi All,
I'm having trouble getting host-to-guest port forwarding to work via
On Sun, Oct 26, 2025 at 02:47:19PM -0500, James Sinton wrote: passt
for a userspace connection:
Please see my post on Superuser for more details:
Sorry it's taken me a while to look at this.
It looks like passt is accepting the ssh connection, but unable to itself connect to the guest. Unfortunately there aren't really any clues as to why, so far.
A couple of easy bits of information which might help: 1. What's the passt version? (`passt --version` on the host) 2. What's the IP configuration within the Windows guest? 3. What's the IP configuration on the host? (`ip addr show` and `ip route show`) 4. What's the output from `ssh -v`
That information might supply some clues, but it's pretty likely we'll need debugging or packet capture output from passt to work this out. Unfortunately, that's a bit trickier than it should be because libvirt doesn't (yet) have the ability to pass the necessary options to passt. Let's start with the information above, then we can work out the steps to get more detailed debugging information if we need it.
-- David Gibson (he or they) | I'll have my music baroque, and my code david AT gibson.dropbear.id.au | minimalist, thank you, not the other way | around. http://www.ozlabs.org/~dgibson
On Thu, 6 Nov 2025 12:08:07 +1100
David Gibson
That information might supply some clues, but it's pretty likely we'll need debugging or packet capture output from passt to work this out. Unfortunately, that's a bit trickier than it should be because libvirt doesn't (yet) have the ability to pass the necessary options to passt.
By the way, this feature request for libvirt is currently tracked at (public RHEL ticket, but applies to libvirt in general): https://issues.redhat.com/browse/RHEL-52281 Meanwhile, one thing you can do is to add a wrapper at /usr/local/bin/passt (don't forget to chmod 755 it) with these lines: --- #!/bin/sh /usr/bin/passt --debug --log-file /tmp/passt.log --pcap /tmp/passt.pcap $@ --- that's the way I currently debug stuff with libvirt, at least. Note that passt can take guest-side packet captures (you would find it at /tmp/passt.pcap, which you can open with Wireshark / tshark later), which is usually convenient for cases like these. -- Stefano
On Wed, Nov 05, 2025 at 11:58:52PM -0600, James Sinton wrote:
Hi David,
Thank you for getting back to me. I have been trying to rehash some of the Arch documentation (https://wiki.archlinux.org/title/Libvirt), and I worked through parts of this tutorial for WinApps as another resource for configuring libvirt to run a Windows guest on a Linux host:
https://github.com/winapps-org/winapps/blob/main/docs/libvirt.md
I think I found that the services for the libvirt daemon were not enabled. I also double checked that the user on the host has been added to the libvirt group.
One tidbit is that the host is connected to the internet via WiFi (wlp6s0), hence, the motivation to use passt in userspace mode.
I'm not really sure why wifi motivates passt particularly, but that's not really relevant either.
A couple of easy bits of information which might help: 1. What's the passt version? (`passt --version` on the host)
passt 2025_09_11.6cbcccc
Ta.
2. What's the IP configuration within the Windows guest?
The windows guest:
Aggregated link speed (Receive/Transmit): 10/10 (Gbps) IPv6 address: fdac:14bf:9c6f:942d:d4:e913:5731:9d0a
This address doesn't match the host, which is unexpected. That suggests that Windows is using SLAAC prefix discovery, but not using DHCPv6 to get the correct exact address. Since your ssh is specifically using IPv4 addresses, this oddity is unlikely to be related to the problem.
Link-local IPv6 address: fe80::5374:1174:7d88:4c94%12 IPv6 default gateway: fe80::11a9:af53:4e56:ea79%12 IPv4 address: 10.0.1.205 IPv4 DNS servers: 10.0.1.1 (Unencrypted) 8.8.8.8 (Unencrypted) Manufacturer: Red Hat, Inc. Description: Red Hat VirtIO Ethernet Adapter Driver version: 100.101.104.28500 Physical address (MAC): 52:54:00:23:01:04
Notice that it matches wlp6s0 below due to the userspace mode config.
Right, making the guest match the host interface configuration is passt default behaviour.
3. What's the IP configuration on the host? (`ip addr show` and `ip route show`)
FYI, I have some docker containers running on the host as well. virbr0 is part of the virsh net. But in userspace mode with port forwarding, I shouldn't need an active bridge network for host-guest communication, correct?
Correct.
$ ip addr show 1: lo:
mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000 link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 inet 127.0.0.1/8 scope host lo valid_lft forever preferred_lft forever inet6 ::1/128 scope host noprefixroute valid_lft forever preferred_lft forever 2: enp7s0: mtu 1500 qdisc mq state DOWN group default qlen 1000 link/ether 24:4b:fe:8e:01:eb brd ff:ff:ff:ff:ff:ff altname enx244bfe8e01eb 3: wlp6s0: mtu 1500 qdisc noqueue state UP group default qlen 1000 link/ether 8c:c6:81:ce:46:0e brd ff:ff:ff:ff:ff:ff altname wlx8cc681ce460e inet 10.0.1.205/24 brd 10.0.1.255 scope global noprefixroute wlp6s0 valid_lft forever preferred_lft forever inet6 fdac:14bf:9c6f:942d:2d42:74ac:5a3:58cd/64 scope global dynamic noprefixroute valid_lft 1726sec preferred_lft 1726sec inet6 fe80::11a9:af53:4e56:ea79/64 scope link noprefixroute valid_lft forever preferred_lft forever
Nothing too odd here that I can spot. [snip]
$ ip route show default via 10.0.1.1 dev wlp6s0 proto static metric 600 10.0.1.0/24 dev wlp6s0 proto kernel scope link src 10.0.1.205 metric 600 172.16.0.0/16 dev br-00cee4dd5f5b proto kernel scope link src 172.16.0.1 172.17.0.0/16 dev docker0 proto kernel scope link src 172.17.0.1 linkdown 172.18.0.0/16 dev br-3d69e1e5d7f4 proto kernel scope link src 172.18.0.1 172.19.0.0/16 dev br-48249c6f88eb proto kernel scope link src 172.19.0.1 192.168.100.0/24 dev virbr0 proto kernel scope link src 192.168.100.1 linkdown
Nor here.
4. What's the output from `ssh -v`
$ ssh -vp 8022 127.0.0.1 debug1: OpenSSH_10.0p2, OpenSSL 3.5.3 16 Sep 2025 debug1: Reading configuration data /etc/ssh/ssh_config debug1: Reading configuration data /etc/ssh/ssh_config.d/20-systemd-ssh-proxy.conf debug1: Reading configuration data /etc/ssh/ssh_config.d/30-libvirt-ssh-proxy.conf debug1: Connecting to 127.0.0.1 [127.0.0.1] port 8022. debug1: Connection established. debug1: identity file . . . debug1: identity file debug1: Local version string SSH-2.0-OpenSSH_10.0 kex_exchange_identification: read: Connection reset by peer Connection reset by 127.0.0.1 port 8022
That's consistent with passt accepting the connection, not managing to contact the guest and so resetting. That's what I expected, but it's useful to confirm. Unfortunately, I have no guesses based on the above information; we're going to need debug logs and/or packet captures. More information on that in reply to Stefano's follow up.
On Wed, Nov 5, 2025 at 7:11 PM David Gibson
wrote: Hi All,
I'm having trouble getting host-to-guest port forwarding to work via
On Sun, Oct 26, 2025 at 02:47:19PM -0500, James Sinton wrote: passt
for a userspace connection:
Please see my post on Superuser for more details:
Sorry it's taken me a while to look at this.
It looks like passt is accepting the ssh connection, but unable to itself connect to the guest. Unfortunately there aren't really any clues as to why, so far.
A couple of easy bits of information which might help: 1. What's the passt version? (`passt --version` on the host) 2. What's the IP configuration within the Windows guest? 3. What's the IP configuration on the host? (`ip addr show` and `ip route show`) 4. What's the output from `ssh -v`
That information might supply some clues, but it's pretty likely we'll need debugging or packet capture output from passt to work this out. Unfortunately, that's a bit trickier than it should be because libvirt doesn't (yet) have the ability to pass the necessary options to passt. Let's start with the information above, then we can work out the steps to get more detailed debugging information if we need it.
-- David Gibson (he or they) | I'll have my music baroque, and my code david AT gibson.dropbear.id.au | minimalist, thank you, not the other way | around. http://www.ozlabs.org/~dgibson
_______________________________________________ user mailing list -- passt-user@passt.top To unsubscribe send an email to passt-user-leave@passt.top
-- David Gibson (he or they) | I'll have my music baroque, and my code david AT gibson.dropbear.id.au | minimalist, thank you, not the other way | around. http://www.ozlabs.org/~dgibson
On Thu, Nov 06, 2025 at 01:37:36PM +0100, Stefano Brivio wrote:
On Thu, 6 Nov 2025 12:08:07 +1100 David Gibson
wrote: That information might supply some clues, but it's pretty likely we'll need debugging or packet capture output from passt to work this out. Unfortunately, that's a bit trickier than it should be because libvirt doesn't (yet) have the ability to pass the necessary options to passt.
By the way, this feature request for libvirt is currently tracked at (public RHEL ticket, but applies to libvirt in general):
https://issues.redhat.com/browse/RHEL-52281
Meanwhile, one thing you can do is to add a wrapper at /usr/local/bin/passt (don't forget to chmod 755 it) with these lines:
--- #!/bin/sh
/usr/bin/passt --debug --log-file /tmp/passt.log --pcap /tmp/passt.pcap $@ ---
that's the way I currently debug stuff with libvirt, at least.
Note that passt can take guest-side packet captures (you would find it at /tmp/passt.pcap, which you can open with Wireshark / tshark later), which is usually convenient for cases like these.
Right. I think this is the way forward, awkward though it is. I was considering an alternative approach: to kill the passt instance started by libvirt and manually restart it with the options we want. That requires a pretty recent qemu to reliably reconnect to the new passt, though, and generally has more places something could go wrong. The wrapper script is the way to go, thanks for the instructions Stefano. -- David Gibson (he or they) | I'll have my music baroque, and my code david AT gibson.dropbear.id.au | minimalist, thank you, not the other way | around. http://www.ozlabs.org/~dgibson
Hi All,
This ended up being an issue with the firewall configuration on the Windows
guest machine. I needed to apply the rule for inbound traffic to the Domain
and Public profiles under the Advanced section of the OpenSSH Server
Properties. The inbound rule defaults to only being applied to the Private
profile (e.g., a Private network). In my case, the Public profile was still
blocking inbound ssh traffic.
After setting up a bridged connection on the guest machine, I encountered a
connection timeout on an ssh access attempt from the host instead of the
almost instantaneous connection reset encountered via the passt port
forward. This triggered me to look deeper into the firewall config on the
guest.
Thank you all for your help and your work on passt! The port forwarding
works, and I can access the guest machine via:
ssh -p 8022 127.0.0.1
Best,
James
On Mon, Nov 10, 2025 at 12:16 AM David Gibson
On Thu, Nov 06, 2025 at 01:37:36PM +0100, Stefano Brivio wrote:
On Thu, 6 Nov 2025 12:08:07 +1100 David Gibson
wrote: That information might supply some clues, but it's pretty likely we'll need debugging or packet capture output from passt to work this out. Unfortunately, that's a bit trickier than it should be because libvirt doesn't (yet) have the ability to pass the necessary options to passt.
By the way, this feature request for libvirt is currently tracked at (public RHEL ticket, but applies to libvirt in general):
https://issues.redhat.com/browse/RHEL-52281
Meanwhile, one thing you can do is to add a wrapper at /usr/local/bin/passt (don't forget to chmod 755 it) with these lines:
--- #!/bin/sh
/usr/bin/passt --debug --log-file /tmp/passt.log --pcap /tmp/passt.pcap $@ ---
that's the way I currently debug stuff with libvirt, at least.
Note that passt can take guest-side packet captures (you would find it at /tmp/passt.pcap, which you can open with Wireshark / tshark later), which is usually convenient for cases like these.
Right. I think this is the way forward, awkward though it is.
I was considering an alternative approach: to kill the passt instance started by libvirt and manually restart it with the options we want. That requires a pretty recent qemu to reliably reconnect to the new passt, though, and generally has more places something could go wrong. The wrapper script is the way to go, thanks for the instructions Stefano.
-- David Gibson (he or they) | I'll have my music baroque, and my code david AT gibson.dropbear.id.au | minimalist, thank you, not the other way | around. http://www.ozlabs.org/~dgibson
participants (3)
-
David Gibson
-
James Sinton
-
Stefano Brivio