I have kvm guest which's netword card is conntected to the host using a tap device. The tap device is part of a bridge on the host together with eth0 so it can access the public network. So far everything works, the guest can access the public network and it can be accessed from the public network.
Now the kvm process on the host provides a vnc server for the guest which listens on 127.0.0.1:5901 on the host. Is there any way to make this vnc server accessible by the ip address which the guest is using (ex. 192.168.0.249), without interrupting the guest from using the same ip (port 5901 is not used by the guest)? It should also work when the guest is not using any ip address at all. So basically I just want to fake IP xx is on the host and only answer/ forward traffic to port 5901 to the host itself.
I tried using this NAT rule on the host, but it doesn't work. Ip forwarding is enabled at the host.
iptables -t nat -A PREROUTING -p tcp --dst 192.168.0.249 --dport 5901 -j DNAT --to-destination 127.0.0.1:5901
I assume this is because the IP 192.168.0.249 is not not bound to any interfaces and so no ARP requests for it get answered and so no packets for this IP arrive at the host. How can make it work? :)
You're on the right track with the iptables rule, but since your host is acting as a bridge, not a router, the packets for your guest never reach the IP layer, which is where iptables operates.
Fortunately, Linux has an equivalent to iptables for the Ethernet layer called ebtables. Using ebtables, you can write this rule:
This rule will match any IP packet destined to that address/port and "redirect" it, which means rewrite its MAC address to be the same as the bridge device it arrived on. This will cause the packet to end up in your IP layer, at which point you can use iptables to DNAT the destination IP address (as you're currently doing).
Most distros' kernels should support ebtables. You may need to install a package ("ebtables" in Debian and Ubuntu) to get the ebtables user space program.