| Tested on | RHEL 10.2 (Coughlan) |
|---|---|
| Package | iproute 6.17.0-2.el10iputils 20240905-5.el10curl 8.12.1-4.el10bind-utils 9.18.33-15.el10_2.2wget 1.24.5-5.el10nmap-ncat 7.92-5.el10 |
| Applies to | RHEL, Rocky Linux, AlmaLinux, Fedora, Debian, Ubuntu, and other Linux distributions with standard networking tools |
| Privilege | Normal user for these checks; elevated privileges may be required only if local system permissions restrict a diagnostic tool |
| Scope | Hostname-first internet checks with curl, ping, and wget, plus routing, DNS, and TCP isolation when those fail. Does not cover proxy server setup, Wi-Fi driver troubleshooting, or full packet capture analysis. |
| Related guides | curl command ping command wget command check whether a port is open nmcli examples |
For a normal “is the internet up?” check, use a hostname such as google.com — you do not need to look up 8.8.8.8 or 1.1.1.1 first. Reserve IP-only probes for later, when a hostname test fails and you want to know whether DNS or routing is the problem.
Quick answer: is the internet up?
The fastest reliable check on most Linux servers is a short HTTPS request to Google's connectivity endpoint:
curl -fsS --max-time 5 -o /dev/null https://www.google.com/generate_204The command prints nothing when it succeeds, so confirm the exit status:
echo $?Sample output:
0Exit status 0 means the host reached the internet over HTTPS. generate_204 returns HTTP 204 with no body, so it is lighter than fetching a full home page.
Many people still try ping google.com first. That is fine for a quick glance, but ICMP to public hosts is often blocked even when web access works:
ping -c 1 -W 2 google.comOn the RHEL 10.2 lab guest used here, curl to generate_204 succeeded while ICMP to google.com showed 100% packet loss — the same pattern you may see on filtered networks.
Check internet connection in a shell script
For automation, keep the probe short and branch on the exit code. This pattern uses the same hostname-based HTTPS check:
#!/usr/bin/env bash
if curl -fsS --max-time 5 -o /dev/null https://www.google.com/generate_204; then
echo "online: https check succeeded"
else
echo "offline: https check failed"
fiSample output when the host can reach the internet:
online: https check succeededWrap the same test in a function when a larger script needs to reuse it:
check_internet_access() {
curl -fsS --max-time 5 -o /dev/null https://www.google.com/generate_204
}Call the function and branch on its exit status:
if check_internet_access; then
echo "online: https check succeeded"
else
echo "offline: https check failed"
fiFor control-flow basics, see Bash if else examples and Bash function examples.
When the quick check fails, work down the stack
One command rarely proves every layer is healthy. After curl or ping to a hostname fails, work in this order:
| Step | Question | Tool |
|---|---|---|
| 1 | Does the kernel know how to reach the internet? | ip route get |
| 2 | Can the host resolve names? | getent hosts or dig |
| 3 | Can the host reach a public IP without DNS? | ping or nc to 1.1.1.1 |
| 4 | Does HTTPS work end to end? | curl to a hostname |
You only need step 3 when step 2 fails or when you suspect DNS is broken. That is the rare case where checking 1.1.1.1 or 8.8.8.8 directly makes sense — not because you memorized the address, but because you are separating “routing works” from “DNS works.”
Check whether Linux has a route to the internet
ip route get asks the kernel which interface, gateway, and source address it would use. It does not contact the remote host, so using a well-known IP here is fine even before DNS is tested:
ip route get 1.1.1.1Sample output:
1.1.1.1 via 10.0.2.2 dev enp0s3 src 10.0.2.15 uid 0
cacheThe via gateway and dev interface confirm a route exists toward the public internet. That still does not prove DNS, firewall rules, or HTTPS access works.
If the command reports the network is unreachable, inspect the IP address, default gateway, and link state first. See nmcli examples when NetworkManager manages the connection.
Ping the default gateway next when you want to confirm local L3 connectivity before blaming the upstream link:
ping -c 1 -W 2 10.0.2.2Sample output:
PING 10.0.2.2 (10.0.2.2) 56(84) bytes of data.
64 bytes from 10.0.2.2: icmp_seq=1 ttl=64 time=0.640 ms
--- 10.0.2.2 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 0.640/0.640/0.640/0.000 msCheck DNS resolution from the command line
DNS answers a different question than “is the internet up?” — can this host convert google.com into an address?
Test through the normal system resolver with getent:
getent hosts google.comSample output:
142.250.67.46 google.comFor DNS-focused output, use dig:
dig +short google.com ASample output:
142.250.67.46If getent hosts google.com fails but ip route get looked fine, check /etc/resolv.conf, NetworkManager DNS settings, or your local resolver before you rerun curl. For BIND administration, see configure a BIND DNS server.
Test reachability without DNS
When hostname checks fail, ping or open a TCP connection to a public IP to see whether the problem is DNS or something lower in the stack.
Ping a public resolver without using DNS:
ping -c 1 -W 2 1.1.1.1On the lab host, ICMP to 1.1.1.1 was filtered even though HTTPS and TCP port 443 succeeded:
PING 1.1.1.1 (1.1.1.1) 56(84) bytes of data.
--- 1.1.1.1 ping statistics ---
1 packets transmitted, 0 received, 100% packet loss, time 0msWhen public ICMP is blocked, use a TCP port check instead. With nc (Ncat on RHEL 10):
nc -vz -w 3 1.1.1.1 443Sample output:
Ncat: Version 7.92 ( https://nmap.org/ncat )
Ncat: Connected to 1.1.1.1:443.
Ncat: 0 bytes sent, 0 bytes received in 0.02 seconds.Bash /dev/tcp works without netcat. This is a Bash feature, not POSIX sh:
timeout 5 bash -c 'cat < /dev/null > /dev/tcp/1.1.1.1/443'The command exits silently on success, so check the status:
echo $?Sample output:
0A successful TCP connection proves the remote IP and port are reachable. It does not prove certificate trust, HTTP responses, or proxy configuration. For broader port troubleshooting, see check whether a port is open in Linux. For more ping options on hostname checks, see the ping command guide.
Check real HTTPS access with curl
Most applications need HTTP or HTTPS to a hostname, not only ICMP or raw TCP. This curl request fetches https://example.com, discards the body, and prints the status code and remote IP:
curl -fsS --max-time 5 -o /dev/null -w 'http_code=%{http_code} remote_ip=%{remote_ip}\n' https://example.comSample output:
http_code=200 remote_ip=87.254.212.120http_code=200 means the HTTPS request succeeded. For a minimal connectivity probe in scripts, generate_204 is still the better default than a random home page:
curl -fsS --max-time 5 -o /dev/null -w 'http_code=%{http_code}\n' https://www.google.com/generate_204Sample output:
http_code=204Useful flags in these examples:
-f— fail on HTTP error responses such as 404 or 500-sS— quiet normal output but still show errors--max-time 5— prevent scripts from hanging-o /dev/null— discard the page body-w— print only the fields you choose
See the curl command guide for more options. If curl is missing, see install cURL on Ubuntu or curl command not found.
http_proxy, https_proxy, or curl proxy options before treating a direct curl test as authoritative. See set up http_proxy and https_proxy.
If curl reports SSL certificate problem: unable to get local issuer certificate while routing looks fine, HTTPS trust is broken — common behind corporate TLS inspection. See fix curl SSL certificate problem behind corporate proxy.
When a website blocks bot or script traffic
A failed curl to a normal website does not always mean the host is offline. Many sites return 403 Forbidden, 503 Service Unavailable, or a challenge page when they detect script clients, missing cookies, or the default curl User-Agent. That is application policy, not proof that routing or DNS is broken.
For generic internet checks in scripts, use endpoints meant for connectivity probes instead of arbitrary home pages:
curl -fsS --max-time 5 -o /dev/null -w 'http_code=%{http_code}\n' https://www.google.com/generate_204http_code=204 means the HTTPS path works. Cloudflare's trace endpoint is another neutral option when you want a short text response:
curl -fsS --max-time 5 https://cloudflare.com/cdn-cgi/traceSample output (trimmed):
fl=1166f85
h=cloudflare.com
ip=87.254.212.121
ts=1786875935.000
visit_scheme=https
uag=curl/8.12.1The ip= line confirms your outbound public address as seen by the remote service.
If HTTP checks keep failing but nc -vz 1.1.1.1 443 succeeds, outbound TCP connectivity to port 443 works. DNS resolution, TLS negotiation, certificate validation, and the HTTP request may still fail separately. In that case:
- Use
generate_204,cdn-cgi/trace, or a TCP port check for a generic online/offline probe - Test your own application's URL only when that specific service is what you need to verify
- Avoid relying on spoofed browser User-Agent strings as your primary fix; sites change bot rules often and some networks forbid impersonation in automation
Check internet access with wget
wget --spider checks whether a URL is reachable without saving the page. Use a hostname, not a bare IP:
wget -q --spider --timeout=5 https://www.google.com/generate_204wget prints nothing when the check succeeds, so read the exit status:
echo $?Sample output:
0Exit status 0 means the URL check succeeded. A non-zero status still requires reading the error message to see whether DNS, TCP, TLS, or HTTP failed. See wget command in Linux or wget command not found if the tool is missing.
Troubleshooting
| Symptom | Likely cause | Fix |
|---|---|---|
curl to google.com fails but getent hosts google.com works |
Firewall, proxy, TLS, or blocked port 443 | Test generate_204; check proxy env vars and corporate TLS inspection |
getent hosts fails but nc -vz 1.1.1.1 443 succeeds |
DNS misconfiguration | Fix /etc/resolv.conf or NetworkManager DNS settings |
ping google.com fails but curl succeeds |
ICMP blocked to public hosts | Use HTTPS or TCP checks instead of ping for internet proof |
ip route get reports network unreachable |
Missing default route or down interface | Fix IP, gateway, or link with NetworkManager or static config |
curl returns HTTP 403 on a normal site |
Bot filtering on that host | Use generate_204, cdn-cgi/trace, or test your app's URL |
ping works but curl fails |
ICMP allowed, HTTP/HTTPS blocked | Check outbound 80/443, proxy, and TLS trust store |
References
- Linux
ip-route(8)manual — https://man7.org/linux/man-pages/man8/ip-route.8.html - Linux
curl(1)manual — https://man7.org/linux/man-pages/man1/curl.1.html - Linux
ping(8)manual — https://man7.org/linux/man-pages/man8/ping.8.html - GNU Wget manual — https://www.gnu.org/software/wget/manual/wget.html
Summary
Checking internet connection on Linux should start the way most operators actually work: probe a hostname with curl -fsS --max-time 5 -o /dev/null https://www.google.com/generate_204, or try ping google.com when you want a fast ICMP glance. You do not need to look up 8.8.8.8 or 1.1.1.1 first, and you should not treat dig or getent as proof the internet works — those tools only test name resolution.
When the quick check fails, work down the stack. Confirm routing with ip route get, test DNS with getent hosts google.com, and use IP-only ping or nc probes only to separate DNS problems from upstream reachability. On filtered networks, ICMP to public addresses often fails while HTTPS still works, which is why script checks should prefer generate_204 over ping.
If a normal website returns 403 to curl but opens in a browser, treat that as bot filtering on that host — not as proof the server lacks internet access. Fall back to generate_204, cdn-cgi/trace, or a TCP port check for a generic probe. Deeper path analysis belongs to tools such as traceroute and tcpdump; see the tcpdump command guide when you need that level of detail.

