kvm libvirt:通过 nft 进行端口转发不起作用

kvm libvirt:通过 nft 进行端口转发不起作用

我使用 KVM 在我的 Host-Debian12 上虚拟化 Guest-Linux-Mint。Guest 显然已通过 NAT 配置良好:我可以从主机通过 SSH 进入 Guest,我可以从 Guest 访问 Internet。但我无法使端口转发正常工作。我想通过 IPv4 和端口 3022 从任何远程计算机通过 SSH 进入 Guest。主机可通过其公共 IPv4 地址从远程计算机访问。nftip6中的 -Tables 由 libvirt 配置。我刚刚在table ip nat

更新 我的 nft-rules 中没有 libvirt 生成的 IPv4 规则。也许这是一个问题。但是我该如何配置 libvirt 来生成这些规则?还是我应该手动配置它们?如果是这样,正确的规则是什么?

sysctl net.ipv4.ip_forward

net.ipv4.ip_forward = 1

nft 列表规则集

table ip6 filter {
    chain LIBVIRT_INP {
    }

    chain INPUT {
        type filter hook input priority filter; policy accept;
        counter packets 3 bytes 208 jump LIBVIRT_INP
    }

    chain LIBVIRT_OUT {
    }

    chain OUTPUT {
        type filter hook output priority filter; policy accept;
        counter packets 42 bytes 2464 jump LIBVIRT_OUT
    }

    chain LIBVIRT_FWO {
    }

    chain FORWARD {
        type filter hook forward priority filter; policy accept;
        counter packets 0 bytes 0 jump LIBVIRT_FWX
        counter packets 0 bytes 0 jump LIBVIRT_FWI
        counter packets 0 bytes 0 jump LIBVIRT_FWO
    }

    chain LIBVIRT_FWI {
    }

    chain LIBVIRT_FWX {
    }
}
table ip6 nat {
    chain LIBVIRT_PRT {
    }

    chain POSTROUTING {
        type nat hook postrouting priority srcnat; policy accept;
        counter packets 0 bytes 0 jump LIBVIRT_PRT
    }
}
table ip6 mangle {
    chain LIBVIRT_PRT {
    }

    chain POSTROUTING {
        type filter hook postrouting priority mangle; policy accept;
        counter packets 42 bytes 2464 jump LIBVIRT_PRT
    }
}
table ip nat {
    chain postrouting {
        type nat hook postrouting priority srcnat; policy accept;
        ip daddr 192.168.122.1 masquerade
    }

    chain prerouting {
        type nat hook prerouting priority dstnat; policy accept;
        tcp dport 3022 dnat to 192.168.122.167:22
    }
}

更新2

因此,我放弃了主机上的所有 nft 规则,并使用了我的 nat 规则添加的这些标准过滤规则:

nft 列表规则集

table inet filter {
    chain input {
        type filter hook input priority filter; policy accept;
    }

    chain forward {
        type filter hook forward priority filter; policy accept;
    }

    chain output {
        type filter hook output priority filter; policy accept;
    }
}
table ip nat {
    chain prerouting {
        type nat hook prerouting priority dstnat; policy accept;
        tcp dport 3022 dnat to 192.168.122.167:22
    }

    chain postrouting {
        type nat hook postrouting priority srcnat; policy accept;
        ip saddr 192.168.122.0/24 masquerade
    }
}

我不明白,为什么 kvm 添加了我在初始帖子中显示的 ip6 规则,但即使使用此规则集,GUEST 也可以访问互联网。所以我对此没意见(我不需要 IPv6)。

但是我还是不知道如何解决我的问题:从 HOST 我能够到达 GUEST 的端口 22 并且通过 ssh 进入机器,但是我不能(这是 HOST 的 IP 地址)。ssh [email protected]ssh -p 3022 [email protected]

我错过了什么?

答案1

Libvirt 通常会设置 netfilter 规则来阻止外部连接到您的虚拟机。例如,我有一个k3sint使用172.17.17.0/24地址范围的 libvirt 网络。Libvirt 在链中生成了以下规则FORWARD

table ip filter {
  chain FORWARD {
    type filter hook forward priority filter; policy accept;
    counter jump LIBVIRT_FWX
    counter jump LIBVIRT_FWI
    counter jump LIBVIRT_FWO
  }

  chain LIBVIRT_FWI {
    oifname "k3sint" ip daddr 172.17.17.0/24 ct state related,established counter accept
    oifname "k3sint" counter reject
  }
}

链中的这些规则LIBVIRT_FWI(FWI ==“前向输入”)会导致任何转发到该地址范围的连接将被拒绝。如果我希望它能正常工作:

table inet mynat {
  chain mynat_PREROUTING {
    type nat hook prerouting priority dstnat + 10; policy accept;
    counter tcp dport 3022 dnat ip to 172.17.17.174:22
  }
}

然后我还需要允许该转发连接。由于 netfilter 的工作方式,我们需要将规则放在链accept中上述规则filter FORWARD之前的某个位置。我们可以通过运行以下reject命令将规则添加到链的前面:LIBVIRT_FWI

nft insert rule ip filter LIBVIRT_FWI \
  counter oifname "k3sint" ip daddr 172.17.17.174 \
  tcp dport 22 accept

现在我可以连接到myhost:3022172.17.17.174 的虚拟机并将其重定向到该连接。

相关内容