Hi,
I’m attempting to get port forwarding to a virtual machine working, for testing purposes its just the ssh port for now. I’ve tried lots of variations, but based on:
my current configuration is:
{ config, pkgs, ... }:
{
virtualisation.libvirtd = {
enable = true;
qemu = {
package = pkgs.qemu_kvm;
runAsRoot = true;
swtpm.enable = true;
ovmf = {
enable = true;
packages = [ (pkgs.OVMF.override {
secureBoot = true;
tpmSupport = true;
}).fd ];
};
};
};
programs.virt-manager.enable = true;
environment.systemPackages = with pkgs; [
virtiofsd
xorriso
];
users.users.alistair = {
extraGroups = [ "libvirtd" ];
};
networking = {
networkmanager.enable = true; # temp
# nftables = {
# enable = true;
# ruleset = ''
# table ip nat {
# chain PREROUTING {
# type nat hook prerouting priority dstnat; policy accept;
# iifname "enp0s20u1u1" tcp dport 22 dnat to 192.168.122.9:22
# }
# }
# '';
# };
firewall.allowedTCPPorts = [ 7022 ];
nat = {
enable = true;
internalInterfaces = [ "enp0s20u1u1" ];
externalInterface = "virbr0";
forwardPorts = [
{
sourcePort = 7022;
proto = "tcp";
destination = "192.168.122.9:22";
}
];
};
};
}
This starts up the network in the VM fine, and I can ssh in from the host, but the port forwarding doesn’t work.
If I uncomment networking.nftables = { ... }
, attempting to start the network results in:
$ sudo virsh net-start default
[sudo] password:
error: Failed to start network default
error: internal error: Failed to apply firewall rules /nix/store/isqrn21fmha9dxf1bbl4mm7j6irpw1x8-iptables-1.8.10/bin/iptables -w --table nat --list-rules: iptables v1.8.10 (nf_tables): table `nat' is incompatible, use 'nft' tool.
and there is no virbr0
device.
Changing the table name as suggested by the error and in another page I found on the web, e.g. table ip natty {
allows the network to start, but then the guest OS isn’t assigned an ip (v4) address.
What am I missing?
Thanks,
Alistair
I finally got this working… the configuration below port forwards to two different VMs, Ubunt22.04
and zmtest01
(this is on my test machine):
kvm.nix
:
{ config, pkgs, ... }:
{
virtualisation.libvirtd = {
enable = true;
qemu = {
package = pkgs.qemu_kvm;
runAsRoot = true;
swtpm.enable = true;
ovmf = {
enable = true;
packages = [ (pkgs.OVMF.override {
secureBoot = true;
tpmSupport = true;
}).fd ];
};
};
# Remember that the hooks and networking.nat.forwardPorts have to agree
hooks.qemu = {
ub2204 = ../files/qemu-hook.sh;
};
};
programs.virt-manager.enable = true;
environment.systemPackages = with pkgs; [
virtiofsd
xorriso
];
users.users.alistair = {
extraGroups = [ "libvirtd" ];
};
networking = {
# Ubuntu22.04 VM: 8022 (SSH), 5901 (VNC)
# zmtest01 VM: 9022 (SSH), 9080 (HTTP), 9440 (HTTPS)
firewall.allowedTCPPorts = [ 8022 5901 9022 9080 9443 ];
nat = {
enable = true;
internalInterfaces = [ "enp0s20u1u1" ];
externalInterface = "virbr0";
forwardPorts = [
{
sourcePort = 8022;
proto = "tcp";
destination = "192.168.122.9:22";
}
{
sourcePort = 5901;
proto = "tcp";
destination = "192.168.122.9:5901";
}
{
sourcePort = 9022;
proto = "tcp";
destination = "192.168.122.4:22";
}
{
sourcePort = 9080;
proto = "tcp";
destination = "192.168.122.4:80";
}
{
sourcePort = 9443;
proto = "tcp";
destination = "192.168.122.4:443";
}
];
};
};
}
../files/qemu-hook.sh
:
#!/run/current-system/sw/bin/bash
echo "qemu-hook: ${1} ${2}" >> /tmp/qemu-hook.log
if [ "${1}" = "zmtest01" ]; then
# SSH on 9022
GUEST_IP="192.168.122.4"
GUEST_PORT="22"
HOST_PORT="9022"
if [ "${2}" = "stopped" ] || [ "${2}" = "reconnect" ]; then
iptables -D FORWARD -o virbr0 -p tcp -d $GUEST_IP --dport $GUEST_PORT -j ACCEPT
iptables -t nat -D PREROUTING -p tcp --dport $HOST_PORT -j DNAT --to $GUEST_IP:$GUEST_PORT
fi
if [ "${2}" = "start" ] || [ "${2}" = "reconnect" ]; then
iptables -I FORWARD -o virbr0 -p tcp -d $GUEST_IP --dport $GUEST_PORT -j ACCEPT
iptables -t nat -I PREROUTING -p tcp --dport $HOST_PORT -j DNAT --to $GUEST_IP:$GUEST_PORT
fi
# HTTP on 9080
GUEST_IP="192.168.122.4"
GUEST_PORT="80"
HOST_PORT="9080"
if [ "${2}" = "stopped" ] || [ "${2}" = "reconnect" ]; then
iptables -D FORWARD -o virbr0 -p tcp -d $GUEST_IP --dport $GUEST_PORT -j ACCEPT
iptables -t nat -D PREROUTING -p tcp --dport $HOST_PORT -j DNAT --to $GUEST_IP:$GUEST_PORT
fi
if [ "${2}" = "start" ] || [ "${2}" = "reconnect" ]; then
iptables -I FORWARD -o virbr0 -p tcp -d $GUEST_IP --dport $GUEST_PORT -j ACCEPT
iptables -t nat -I PREROUTING -p tcp --dport $HOST_PORT -j DNAT --to $GUEST_IP:$GUEST_PORT
fi
# HTTPS on 9443
GUEST_IP="192.168.122.4"
GUEST_PORT="443"
HOST_PORT="9443"
if [ "${2}" = "stopped" ] || [ "${2}" = "reconnect" ]; then
iptables -D FORWARD -o virbr0 -p tcp -d $GUEST_IP --dport $GUEST_PORT -j ACCEPT
iptables -t nat -D PREROUTING -p tcp --dport $HOST_PORT -j DNAT --to $GUEST_IP:$GUEST_PORT
fi
if [ "${2}" = "start" ] || [ "${2}" = "reconnect" ]; then
iptables -I FORWARD -o virbr0 -p tcp -d $GUEST_IP --dport $GUEST_PORT -j ACCEPT
iptables -t nat -I PREROUTING -p tcp --dport $HOST_PORT -j DNAT --to $GUEST_IP:$GUEST_PORT
fi
fi
if [ "${1}" = "ubuntu22.04" ]; then
# SSH on 8022
GUEST_IP="192.168.122.9"
GUEST_PORT="22"
HOST_PORT="8022"
if [ "${2}" = "stopped" ] || [ "${2}" = "reconnect" ]; then
iptables -D FORWARD -o virbr0 -p tcp -d $GUEST_IP --dport $GUEST_PORT -j ACCEPT
iptables -t nat -D PREROUTING -p tcp --dport $HOST_PORT -j DNAT --to $GUEST_IP:$GUEST_PORT
fi
if [ "${2}" = "start" ] || [ "${2}" = "reconnect" ]; then
iptables -I FORWARD -o virbr0 -p tcp -d $GUEST_IP --dport $GUEST_PORT -j ACCEPT
iptables -t nat -I PREROUTING -p tcp --dport $HOST_PORT -j DNAT --to $GUEST_IP:$GUEST_PORT
fi
# VNC stays on 5901
GUEST_IP="192.168.122.9"
GUEST_PORT="5901"
HOST_PORT="5901"
if [ "${2}" = "stopped" ] || [ "${2}" = "reconnect" ]; then
iptables -D FORWARD -o virbr0 -p tcp -d $GUEST_IP --dport $GUEST_PORT -j ACCEPT
iptables -t nat -D PREROUTING -p tcp --dport $HOST_PORT -j DNAT --to $GUEST_IP:$GUEST_PORT
fi
if [ "${2}" = "start" ] || [ "${2}" = "reconnect" ]; then
iptables -I FORWARD -o virbr0 -p tcp -d $GUEST_IP --dport $GUEST_PORT -j ACCEPT
iptables -t nat -I PREROUTING -p tcp --dport $HOST_PORT -j DNAT --to $GUEST_IP:$GUEST_PORT
fi
fi
Hope this helps someone else.
1 Like