KVM/virt-manager
There appears to be a relevant tutorial here. There are two steps, summarized below: (1) Assign a static IP address to the VM; and (2) Configure the firewall for port forwarding.
Assign a static IP address to the VM.
List the available networks
$ virsh net-list
Name State Autostart Persistent
----------------------------------------------------------
xhubnet active yes yes
This gives you the name of the one you want.
List the network information (for network xhubnet
in this case)
$ virsh net-dumpxml xhubnet
<network>
<name>xhubnet</name>
<uuid>2ba36c4f-46c9-4767-a9fc-6808cf001a19</uuid>
<forward mode='nat'>
<nat>
<port start='1024' end='65535'/>
</nat>
</forward>
<bridge name='virbr1' stp='on' delay='0'/>
<mac address='52:54:00:8e:b5:88'/>
<domain name='xhubnet'/>
<ip address='192.168.111.1' netmask='255.255.255.0'>
<dhcp>
<range start='192.168.111.120' end='192.168.111.254'/>
</dhcp>
</ip>
</network>
This tells you the DHCP range, so you can choose an appropriate address.
Get the MAC address of your VM.
$ virsh dumpxml VM_NAME | grep -i '<mac'
<mac address='52:54:00:e2:95:c6'/>
Edit the network configuration to request a static IP address for your VM. Run virsh net-edit <DOMAIN_NAME>
(in this case, virsh net-edit xhubnet
), and add the following line after the <range ...>
section:
<host mac='52:54:00:e2:95:c6' name='VM_NAME' ip='192.168.111.36'/>
Request the static IP address by restarting the network:
$ virsh net-destroy xhubnet
$ virsh net-start xhubnet
If this doesn't work, try restarting the libvirt-bin
service on your Linux host:
$ virsh shutdown VM_NAME
$ /etc/init.d/libvirt-bin restart
$ virsh start VM_NAME
$ ping -a 192.168.111.36
Configure port forwarding on the firewall
Allow connections from the WAN. On your host machine, alter the iptables
rules in the following way. Suppose that you're forwarding port 9867 on the host to port 22 on your Windows guest, using the static IP address set above (192.168.111.36
):
# connections from outside
$ iptables -I FORWARD -o virbr1 -d 192.168.111.36 -j ACCEPT
$ iptables -t nat -I PREROUTING -p tcp --dport 9867 -j DNAT --to 192.168.111.36:22
Masquerade the local subnet
# Masquerade local subnet
$ iptables -I FORWARD -o virbr1 -d 192.168.111.36 -j ACCEPT
$ iptables -t nat -A POSTROUTING -s 192.168.111.0/24 -j MASQUERADE
$ iptables -A FORWARD -o virbr1 -m state --state RELATED,ESTABLISHED -j ACCEPT
$ iptables -A FORWARD -i virbr1 -o eth0 -j ACCEPT
$ iptables -A FORWARD -i virbr1 -o lo -j ACCEPT
Make the changes persistent
$ service netfilter-persistent save
$ service netfilter-persistent reload
This should make the specified port on the VM available through your host's public IP address. If your host sits behind a router and uses the router's public IP, you may need to configure router port forwarding rules to forward traffic to your host's private IP on the correct port.
Also configure any necessary inbound traffic rules in the Windows Firewall on your Windows VM.
Oracle VirtualBox
If you are using Oracle VirtualBox with the NAT network interface, there is an option to set up port forwarding rules.
Set the host IP to be blank (or 0.0.0.0
) to listen for connections from all computers on the local subnet, or 127.0.0.1
to accept connections only from the same computer. To find the private IP address of your guest OS, use something like ipconfig
or ip addr
.
You could also set Attached to:
to Bridged Adapter
, so that your virtual machine shows up as its own device on the network. You can then configure the guest OS and host router's firewall settings to enable access without having to go through your host OS.