I'm using a host-only network in virtualbox.
The host (Windows): 192.168.56.1/24
The guest (CentOS): 192.168.56.101/24
There's a simple http server which listens on 0.0.0.0:8080 running in the guest.
"curl http://192.168.56.101:8080/" in the guest machine is OK. But it doesn't work in the host (visited by a browser as curl isn't installed on my Windows).
Ping 192.168.56.101 from the host is OK though. I try to gain some hints by capturing packets on the VirualBox-Host-Only-Network adapter with wireshark. And I see some ICMP packets sent from 192.168.56.101 to 192.168.56.1 which tell me "Destination unreachable (Host administratively prohibited)".
I can visit http://192.168.56.101:8080/ only if I shut down the firewall of the guest (systemctl stop firewalld
). But I don't want to do that. I'd like to visit http://192.168.56.101:8080/ from the host while the firewall of the guest is on.
I have searched this for a while and still don't know exactly how. Maybe something with iptables but not familiar with it and feel a little hard to understand. Can someone explain how the following rules work to reject my visit and how to modify it properly (for example in the above situation)?
Thank you.
iptables -nvL --line-numbers (when the firewall is off)
Chain INPUT (policy ACCEPT 72 packets, 6371 bytes)
num pkts bytes target prot opt in out source destination
Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
num pkts bytes target prot opt in out source destination
Chain OUTPUT (policy ACCEPT 51 packets, 9866 bytes)
num pkts bytes target prot opt in out source destination
iptables -nvL --line-numbers (when the firewall is on)
Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
num pkts bytes target prot opt in out source destination
1 0 0 ACCEPT udp -- virbr0 * 0.0.0.0/0 0.0.0.0/0 udp dpt:53
2 0 0 ACCEPT tcp -- virbr0 * 0.0.0.0/0 0.0.0.0/0 tcp dpt:53
3 0 0 ACCEPT udp -- virbr0 * 0.0.0.0/0 0.0.0.0/0 udp dpt:67
4 0 0 ACCEPT tcp -- virbr0 * 0.0.0.0/0 0.0.0.0/0 tcp dpt:67
5 1 76 ACCEPT all -- * * 0.0.0.0/0 0.0.0.0/0 ctstate RELATED,ESTABLISHED
6 0 0 ACCEPT all -- lo * 0.0.0.0/0 0.0.0.0/0
7 11 1096 INPUT_direct all -- * * 0.0.0.0/0 0.0.0.0/0
8 11 1096 INPUT_ZONES_SOURCE all -- * * 0.0.0.0/0 0.0.0.0/0
9 11 1096 INPUT_ZONES all -- * * 0.0.0.0/0 0.0.0.0/0
10 0 0 DROP all -- * * 0.0.0.0/0 0.0.0.0/0 ctstate INVALID
11 11 1096 REJECT all -- * * 0.0.0.0/0 0.0.0.0/0 reject-with icmp-host-prohibited
Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
num pkts bytes target prot opt in out source destination
1 0 0 ACCEPT all -- * virbr0 0.0.0.0/0 192.168.122.0/24 ctstate RELATED,ESTABLISHED
2 0 0 ACCEPT all -- virbr0 * 192.168.122.0/24 0.0.0.0/0
3 0 0 ACCEPT all -- virbr0 virbr0 0.0.0.0/0 0.0.0.0/0
4 0 0 REJECT all -- * virbr0 0.0.0.0/0 0.0.0.0/0 reject-with icmp-port-unreachable
5 0 0 REJECT all -- virbr0 * 0.0.0.0/0 0.0.0.0/0 reject-with icmp-port-unreachable
6 0 0 ACCEPT all -- * * 0.0.0.0/0 0.0.0.0/0 ctstate RELATED,ESTABLISHED
7 0 0 ACCEPT all -- lo * 0.0.0.0/0 0.0.0.0/0
8 0 0 FORWARD_direct all -- * * 0.0.0.0/0 0.0.0.0/0
9 0 0 FORWARD_IN_ZONES_SOURCE all -- * * 0.0.0.0/0 0.0.0.0/0
10 0 0 FORWARD_IN_ZONES all -- * * 0.0.0.0/0 0.0.0.0/0
11 0 0 FORWARD_OUT_ZONES_SOURCE all -- * * 0.0.0.0/0 0.0.0.0/0
12 0 0 FORWARD_OUT_ZONES all -- * * 0.0.0.0/0 0.0.0.0/0
13 0 0 DROP all -- * * 0.0.0.0/0 0.0.0.0/0 ctstate INVALID
14 0 0 REJECT all -- * * 0.0.0.0/0 0.0.0.0/0 reject-with icmp-host-prohibited
Chain OUTPUT (policy ACCEPT 12 packets, 1204 bytes)
num pkts bytes target prot opt in out source destination
1 0 0 ACCEPT udp -- * virbr0 0.0.0.0/0 0.0.0.0/0 udp dpt:68
2 12 1204 OUTPUT_direct all -- * * 0.0.0.0/0 0.0.0.0/0
Chain FORWARD_IN_ZONES (1 references)
num pkts bytes target prot opt in out source destination
1 0 0 FWDI_public all -- enp0s8 * 0.0.0.0/0 0.0.0.0/0 [goto]
2 0 0 FWDI_public all -- enp0s3 * 0.0.0.0/0 0.0.0.0/0 [goto]
3 0 0 FWDI_public all -- + * 0.0.0.0/0 0.0.0.0/0 [goto]
Chain FORWARD_IN_ZONES_SOURCE (1 references)
num pkts bytes target prot opt in out source destination
Chain FORWARD_OUT_ZONES (1 references)
num pkts bytes target prot opt in out source destination
1 0 0 FWDO_public all -- * enp0s8 0.0.0.0/0 0.0.0.0/0 [goto]
2 0 0 FWDO_public all -- * enp0s3 0.0.0.0/0 0.0.0.0/0 [goto]
3 0 0 FWDO_public all -- * + 0.0.0.0/0 0.0.0.0/0 [goto]
Chain FORWARD_OUT_ZONES_SOURCE (1 references)
num pkts bytes target prot opt in out source destination
Chain FORWARD_direct (1 references)
num pkts bytes target prot opt in out source destination
Chain FWDI_public (3 references)
num pkts bytes target prot opt in out source destination
1 0 0 FWDI_public_log all -- * * 0.0.0.0/0 0.0.0.0/0
2 0 0 FWDI_public_deny all -- * * 0.0.0.0/0 0.0.0.0/0
3 0 0 FWDI_public_allow all -- * * 0.0.0.0/0 0.0.0.0/0
4 0 0 ACCEPT icmp -- * * 0.0.0.0/0 0.0.0.0/0
Chain FWDI_public_allow (1 references)
num pkts bytes target prot opt in out source destination
Chain FWDI_public_deny (1 references)
num pkts bytes target prot opt in out source destination
Chain FWDI_public_log (1 references)
num pkts bytes target prot opt in out source destination
Chain FWDO_public (3 references)
num pkts bytes target prot opt in out source destination
1 0 0 FWDO_public_log all -- * * 0.0.0.0/0 0.0.0.0/0
2 0 0 FWDO_public_deny all -- * * 0.0.0.0/0 0.0.0.0/0
3 0 0 FWDO_public_allow all -- * * 0.0.0.0/0 0.0.0.0/0
Chain FWDO_public_allow (1 references)
num pkts bytes target prot opt in out source destination
Chain FWDO_public_deny (1 references)
num pkts bytes target prot opt in out source destination
Chain FWDO_public_log (1 references)
num pkts bytes target prot opt in out source destination
Chain INPUT_ZONES (1 references)
num pkts bytes target prot opt in out source destination
1 11 1096 IN_public all -- enp0s8 * 0.0.0.0/0 0.0.0.0/0 [goto]
2 0 0 IN_public all -- enp0s3 * 0.0.0.0/0 0.0.0.0/0 [goto]
3 0 0 IN_public all -- + * 0.0.0.0/0 0.0.0.0/0 [goto]
Chain INPUT_ZONES_SOURCE (1 references)
num pkts bytes target prot opt in out source destination
Chain INPUT_direct (1 references)
num pkts bytes target prot opt in out source destination
Chain IN_public (3 references)
num pkts bytes target prot opt in out source destination
1 11 1096 IN_public_log all -- * * 0.0.0.0/0 0.0.0.0/0
2 11 1096 IN_public_deny all -- * * 0.0.0.0/0 0.0.0.0/0
3 11 1096 IN_public_allow all -- * * 0.0.0.0/0 0.0.0.0/0
4 0 0 ACCEPT icmp -- * * 0.0.0.0/0 0.0.0.0/0
Chain IN_public_allow (1 references)
num pkts bytes target prot opt in out source destination
1 0 0 ACCEPT tcp -- * * 0.0.0.0/0 0.0.0.0/0 tcp dpt:22 ctstate NEW
Chain IN_public_deny (1 references)
num pkts bytes target prot opt in out source destination
Chain IN_public_log (1 references)
num pkts bytes target prot opt in out source destination
Chain OUTPUT_direct (1 references)
num pkts bytes target prot opt in out source destination
With ip addr
:
enp0s3: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 10.0.2.15 netmask 255.255.255.0 broadcast 10.0.2.255
enp0s8: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 192.168.56.101 netmask 255.255.255.0 broadcast 192.168.56.255
Interface enp0s3 is to use NAT and enp0s8 connects to host-only network. Both lo and virbr0 are not relevant and not listed here.
Best Answer
Using
firewall-cmd
, open the port8080/tcp
, once in the active rules (only triggering a rebuild of theiptables
rules with the change) and once in the saved configuration (only saving the change in the configuration in/etc/firewalld/
).UPDATE: allow a whole interface, as asked in comment.
firewalld
has a concept of zones. By default actions are done on thepublic
zone., but there are many predefined zones, egdmz
,work
, ... and thetrusted
zone which implicitly trusts everything. The easiest to allow an interface, is to add this interface to thetrusted
zone. As usual the two command are, once for the configuration (with--permanent
) once for the active set (without--permanent
.--reload
could also work).iptables rules will have rules changed accordingly with among them those key rules, visible in the output of
iptables-save
(I'm just writing a few here, there are many more):Now for example a remote incoming tcp connection to a random port (on an address) on this interface will likely switch from "No route to host" or other "Destination unreachable" error to "Connection refused" error unless there really is a process listening on it.
There are some issues, possibly distribution-dependent for it to always work properly, including after reboot, even if it appears to be fine at start. Example:
Firewalld Adding Interfaces to a Zone Issue
Really, once going beyond the task of opening a few ports, using
firewalld
instead of directly making one own's rules withiptables
can become convoluted, and requires investment in the knowledge of its syntax, which could have been spent in the lower layer's knowledge instead (todayiptables
, tomorrownft
...), and requires anyway verifying the results today withiptables-save
(tomorrow might becomenft list ruleset -a
).