Hi,

I hit a libvirt networking problem that guest cannot access host HTTP service. 
I debug this issue and tried some efforts.  Thanks for your suggestions!

Environment
-------------
guest IP: 192.168.122.46   (Linux, default NAT, installed using virt-manager)
host1 IP: 192.168.3.16     (Centos 8.5 running libvirt and qemu, default 
libvirt iptable rules)
HTTP service: 192.168.3.16:70    (firewall rules have allowed this port)

host2: 192.168.3.65:70  (for test only)

guest network xml
<interface type="network">
  <mac address="52:54:00:f5:a8:9f"/>
  <source network="default" portid="6e8ce7e7-6517-43fa-b113-aaddb6c1bc08" 
bridge="virbr0"/>
  <target dev="vnet2"/>
  <model type="e1000"/>
  <alias name="net0"/>
  <address type="pci" domain="0x0000" bus="0x00" slot="0x03" function="0x0"/>
</interface>


1. guest and host1/host2 can ping each other
2. *guest can visit host2 HTTP
3. *guest cannot visit host1 HTTP

When I capture traffic in guest, Wireshark shows:
192.168.122.46 -> 192.168.3.16    // SYN ok
192.168.122.46 <- 192.168.3.16    // Destination unreachable (Port unreachable)

guest route table:
------------------
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
0.0.0.0         192.168.122.1   0.0.0.0         UG    100    0        0 eth0
192.168.122.0   0.0.0.0         255.255.255.0   U     100    0        0 eth0

host1 route table:
------------------
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
0.0.0.0         192.168.3.1     0.0.0.0         UG    100    0        0 enp3s0
192.168.3.0     0.0.0.0         255.255.255.0   U     100    0        0 enp3s0
192.168.122.0   0.0.0.0         255.255.255.0   UG    0      0        0 virbr0


I delete the last rule and add a rule to make sure host1 visits guests will go 
through 192.168.122.1
------------------
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
(other rules omitted)
192.168.122.0   192.168.122.1   255.255.255.0   UG    0      0        0 virbr0


However, traceroute shows this new rule does not work (which should go to 
192.168.122.1 first), and guest cannot visit host1 HTTP request.


 [!] guest visit http://192.168.3.16:70 does not go through 192.168.122.1
traceroute 192.168.122.46
traceroute to 192.168.122.46 (192.168.122.46), 30 hops max, 60 byte packets
1  192.168.122.46 (192.168.122.46)  0.200 ms  0.194 ms  0.194 ms

# guest visit http://192.168.3.65:70 goes through 192.168.122.1
traceroute 192.168.3.65
traceroute to 192.168.3.65 (192.168.3.65), 30 hops max, 60 byte packets
 1  192.168.122.1 (192.168.122.1)  0.244 ms  0.050 ms  0.120 ms
 2  192.168.3.65 (192.168.3.65)  0.823 ms !X  0.802 ms !X  0.789 ms !X

 In sum, is there a way to force the guest go through 192.168.122.1 when 
visiting the hosting machine?

-------------------
libvirt iptable rules:
-P INPUT ACCEPT
-P FORWARD ACCEPT
-P OUTPUT ACCEPT
-N LIBVIRT_INP
-N LIBVIRT_OUT
-N LIBVIRT_FWO
-N LIBVIRT_FWI
-N LIBVIRT_FWX
-A INPUT -j LIBVIRT_INP
-A FORWARD -j LIBVIRT_FWX
-A FORWARD -j LIBVIRT_FWI
-A FORWARD -j LIBVIRT_FWO
-A OUTPUT -j LIBVIRT_OUT
-A LIBVIRT_INP -i virbr0 -p udp -m udp --dport 53 -j ACCEPT
-A LIBVIRT_INP -i virbr0 -p tcp -m tcp --dport 53 -j ACCEPT
-A LIBVIRT_INP -i virbr0 -p udp -m udp --dport 67 -j ACCEPT
-A LIBVIRT_INP -i virbr0 -p tcp -m tcp --dport 67 -j ACCEPT
-A LIBVIRT_OUT -o virbr0 -p udp -m udp --dport 53 -j ACCEPT
-A LIBVIRT_OUT -o virbr0 -p tcp -m tcp --dport 53 -j ACCEPT
-A LIBVIRT_OUT -o virbr0 -p udp -m udp --dport 68 -j ACCEPT
-A LIBVIRT_OUT -o virbr0 -p tcp -m tcp --dport 68 -j ACCEPT
-A LIBVIRT_FWO -s 192.168.122.0/24 -i virbr0 -j ACCEPT
-A LIBVIRT_FWO -i virbr0 -j REJECT --reject-with icmp-port-unreachable    # 
delete this rule does not work
-A LIBVIRT_FWI -d 192.168.122.0/24 -o virbr0 -m conntrack --ctstate 
RELATED,ESTABLISHED -j ACCEPT
-A LIBVIRT_FWI -o virbr0 -j REJECT --reject-with icmp-port-unreachable    # 
delete this rule does not work
-A LIBVIRT_FWX -i virbr0 -o virbr0 -j ACCEPT

Reply via email to