0

I just set up a new CentOS 8 on my server with a VM on it, and I wanted to forward a port from the host to the VM (2228 to 22) with firewalld. I added the port-forward, turned on masquerade and tried it out from my desktop and this was the output:

ssh: connect to host x.x.x.x port 2228: Connection refused

I already checked if ip forwarding was enabled on the system and checked if I can reach the VM from the host, which I can. I also tried turning off SELinux but it didn't change anything. Interestingly enough, a port forward only on the host (e.g. Host:1234 to Host:22) works.

This is my firewalld zone:

public (active)
  target: default
  icmp-block-inversion: no
  interfaces: enp3s0
  sources: 
  services: dhcpv6-client ssh
  ports: 
  protocols: 
  masquerade: yes
  forward-ports: port=2228:proto=tcp:toport=22:toaddr=192.168.122.8
  source-ports: 
  icmp-blocks: 
  rich rules: 

Running nmap on port 2228 returns that the port is closed and not filtered, so something seems to be working, just not all of it.

As suggested by J D I added a rich rule with logging but it does not seem to work either:

`rule family="ipv4" forward-port port="2228" protocol="tcp" to-port="22" to-addr="192.168.122.8" log prefix="forward-log" level="debug"`
ZofiaZementa
  • 1
  • 1
  • 3

3 Answers3

0

Add virbrX to a trusted zone and try again: firewall-cmd --add-interface=virbr0 --zone=trusted.

J D
  • 163
  • 1
  • 9
  • That unfortunately didn't change anything, ssh and nmap output is still the same – ZofiaZementa Mar 03 '20 at 11:56
  • did you set the --permanent flag when configuring? If so, did you reload config? Lacking better ideas, I'd run `tcpdump -i any port 22` to see if there are hits. If there aren't, then set up a rich rule with a log. – J D Mar 03 '20 at 12:10
  • Yes I added it permanently and I reloaded. The tcpdump showed, that the packages are arriving at the host, but not the guest. I made the rule, but since i don't have very much experience with rich rules, it might not be right (i added the rule to the post), at least when i try it, the result is the same, and there are no entries in the syslog – ZofiaZementa Mar 03 '20 at 14:12
0

So it turns out that the problem wasn't with firewalld, but with the libvirt network config. Due to the virtual network being a nat network and not a routed network, the packets firewalld forwarded, coulnd't reach the vm. I had to change the network config by running sudo virsh net-edit default and change out the value of forward from nat to route so it looks something like this:

<network connections='4'>
  <name>default</name>
  <uuid>b812951c-2f19-4e62-83ad-a73a3f1ca529</uuid>
  <forward mode='route'/>
  <bridge name='virbr0' stp='on' delay='0'/>
  <mac address='52:54:00:75:97:4e'/>
  <ip address='192.168.122.1' netmask='255.255.255.0'>
    <dhcp>
      <range start='192.168.122.2' end='192.168.122.254'/>
    </dhcp>
  </ip>
</network>

Reboot and it works!

EDIT

Teutocat is right, this is not a solution and may even harm your network. Though like he said, his is only a quick and dirty hack. The best "solution" I found is using a small piece of software called libvirt-hook-qemu. If you wanna know how to set it up or why exactly it is even needed, see this post: https://superuser.com/a/1475915

ZofiaZementa
  • 1
  • 1
  • 3
0

Changing forward mode from nat to route is no solution if masqerading outgoing guest traffic is required. My quick and dirty hack is

iptables -I FORWARD -o virbr0 --proto tcp --dport 22 -d 192.168.122.8 -m conntrack --ctstate NEW -j ACCEPT

But this must be applied after every firewall-cmd --reload.

It seems that libvirt takes no respect of FirewalldBackend (nftables by default on CentOS 8) and iptables hook has precedence over nftables.