Diagnosing connection problems
"It does not connect" has many causes. Work from the symptom through four layers, in order, and you find the answer quickly instead of guessing, or worse, switching the firewall off.
- Read the symptom: rejected, dropped or refused.
- Check the service, the listening port, the zone rules and the SELinux port label in turn.
- Test a port from another machine without special tools.
Four layers
Four layers, in order: Step through what to check when a client cannot connect.
What the client sees
What the client sees: Select a symptom.
Test from the client with curl. A bare TCP check works with bash alone, too:
[student@serverb ~]$ curl -sS -m 3 http://servera/
curl: (7) Failed to connect to servera port 80: No route to host
[student@serverb ~]$ (: </dev/tcp/servera/22) && echo ssh-open
ssh-openping is not a reliable test: it uses another protocol and can succeed while a port is blocked.
On the server, layer by layer
[root@servera ~]# systemctl is-active httpd
active
[root@servera ~]# ss -tlnp | grep httpd | cut -c1-60
LISTEN 0 511 *:80 *:*
[root@servera ~]# firewall-cmd --get-active-zones
public
interfaces: enp1s0
[root@servera ~]# firewall-cmd --list-services
cockpit dhcpv6-client ssh- The service is running and listens on every address (
*:80), so layers 1 and 2 are fine. - The zone that judges serverb is
public, andhttpis missing. That is the answer.
If the listening address were 127.0.0.1:80, the firewall would not matter: the daemon accepts only local connections. Fix its Listen setting instead.
If a source is assigned to a zone, compare with firewall-cmd --get-zone-of-source=ADDRESS, and list that zone with --list-all --zone=NAME; it may be a different zone from the interface's.
Fix the right layer
[root@servera ~]# firewall-cmd --permanent --add-service=http; firewall-cmd --reload
success
success
[student@serverb ~]$ curl -s -m 3 http://servera/
hello from serveraWhen the cause is an unusual port, remember there are two gates: the firewall (this chapter) and the SELinux port label (chapter 16: semanage port -a -t http_port_t -p tcp 82). The first protects the network; the second decides which ports the daemon may use.
Try it
Check your understanding
- curl says "No route to host" but ping works. What is the first suspect?
- curl says "Connection refused". What does that suggest?
- curl waits and then times out. Which firewall setting fits?
- Which command shows what listens on which port, with the program?
- httpd listens on 127.0.0.1:80 only. A client on the network fails. Is it the firewall?
- Where do you read the packets that a zone rejects?