如何在 Linux 中使用 curl 测试服务器连通性

LinuxBeginner
立即练习

介绍

在 Linux 系统管理中,检查服务器连通性是一项基本技能。本教程将指导你使用 cURL 工具测试服务器连通性的过程。cURL (Client URL) 是一个命令行实用程序,它允许通过各种网络协议传输数据,这使得它成为网络诊断和故障排除的必备工具。

通过本教程的学习,你将了解如何使用 cURL 来验证服务器可用性、检查响应时间、分析 HTTP 状态码以及排除连接问题。无论你是在管理 Web 服务器、API 还是 Linux 环境中的任何网络服务,这些技能都非常有用。

这是一个实验(Guided Lab),提供逐步指导来帮助你学习和实践。请仔细按照说明完成每个步骤,获得实际操作经验。根据历史数据,这是一个 初级 级别的实验,完成率为 82%。获得了学习者 98% 的好评率。

理解 cURL 基础

cURL 是一个强大的命令行工具,允许你使用各种协议传输数据,包括 HTTP、HTTPS、FTP 等等。在深入研究连通性测试之前,让我们先了解一下 cURL 是什么,以及如何使用它进行基本操作。

安装 cURL

cURL 实用程序已预先安装在大多数 Linux 发行版上,包括你的 Ubuntu 22.04 环境。要验证 cURL 是否已安装,请打开你的终端并运行:

curl --version

你应该看到类似这样的输出:

curl 7.81.0 (x86_64-pc-linux-gnu) libcurl/7.81.0 OpenSSL/3.0.2 zlib/1.2.11 brotli/1.0.9 zstd/1.4.8 libidn2/2.3.2 libpsl/0.21.0 (+libidn2/2.3.2) libssh/0.9.6/openssl/zlib nghttp2/1.43.0 librtmp/2.3 OpenLDAP/2.5.13
Release-Date: 2022-01-05
Protocols: dict file ftp ftps gopher gophers http https imap imaps ldap ldaps mqtt pop3 pop3s rtmp rtsp scp sftp smb smbs smtp smtps telnet tftp
Features: alt-svc AsynchDNS brotli GSS-API HSTS HTTP2 HTTPS-proxy IDN IPv6 Kerberos Largefile libz NTLM NTLM_WB PSL SPNEGO SSL TLS-SRP UnixSockets zstd

这确认了 cURL 已安装,并显示了版本以及支持的协议和功能。

基本 cURL 语法

使用 cURL 的基本语法是:

curl [options] [URL]

让我们尝试一个简单的 cURL 命令来检索网站的内容:

curl https://example.com

此命令向 example.com 发送一个 GET 请求,并在你的终端中显示 HTML 响应。你应该看到类似于以下的 HTML 代码:

<!doctype html>
<html>
  <head>
    <title>Example Domain</title>
    <!-- More HTML content -->
  </head>
  <body>
    <div>
      <h1>Example Domain</h1>
      <p>This domain is for use in illustrative examples in documents...</p>
      <!-- More content -->
    </div>
  </body>
</html>

将输出保存到文件

除了在终端中显示输出之外,你还可以使用 -o--output 选项将其保存到文件中:

curl -o example.html https://example.com

此命令将 example.com 的响应保存到名为 example.html 的文件中。要验证文件是否已创建:

ls -l example.html

你应该看到确认文件存在的输出:

-rw-rw-r-- 1 labex labex 1256 Mar 28 12:34 example.html

要查看文件的内容:

cat example.html

你应该看到与之前在终端中显示的相同的 HTML 内容。

理解 cURL 的 HTTP 方法

cURL 默认使用 HTTP GET 方法,但你可以使用 -X 选项指定其他方法。常见的 HTTP 方法包括:

  • GET:从服务器检索数据
  • POST:向服务器提交数据
  • PUT:更新服务器上的现有数据
  • DELETE:从服务器删除数据
  • HEAD:类似于 GET,但仅检索标头

在后面的步骤中,我们将探讨如何使用这些不同的方法来测试服务器连通性和功能。

测试基本服务器连通性

现在你已经了解了 cURL 的基础知识,让我们使用它来测试服务器连通性。检查服务器是否启动并正确响应的能力是系统管理员和开发人员的一项关键技能。

简单的连接测试

最基本的连通性测试是向服务器发送一个请求,看看它是否响应。让我们测试与 Google 服务器的连通性:

curl -I https://www.google.com

-I 选项(或 --head)告诉 cURL 发送一个 HEAD 请求,该请求仅检索标头,而不包含正文内容。这对于快速连通性检查很有用。你应该看到类似这样的输出:

HTTP/2 200
content-type: text/html; charset=ISO-8859-1
date: Tue, 28 Mar 2023 12:34:56 GMT
server: gws
content-length: 219
x-xss-protection: 0
x-frame-options: SAMEORIGIN

HTTP/2 200 表示连接成功——服务器已启动并正在响应。

检查 HTTP 状态码

HTTP 状态码是服务器发送的标准化响应,用于指示客户端请求的结果。一些常见状态码包括:

  • 200:OK - 请求成功
  • 301/302:重定向 - 资源已移动
  • 404:未找到 - 资源不存在
  • 500:内部服务器错误 - 服务器遇到错误

让我们测试一个不存在的 URL,看看 404 响应:

curl -I https://www.google.com/nonexistent-page

输出应包含 404 状态码:

HTTP/2 404
content-type: text/html; charset=UTF-8
date: Tue, 28 Mar 2023 12:35:01 GMT
server: gws
content-length: 1565
...

测量响应时间

要测量服务器响应所需的时间,请使用 -w 选项和格式字符串:

curl -s -o /dev/null -w "Connect: %{time_connect}s\nTotal: %{time_total}s\n" https://www.google.com

此命令:

  • -s:在静默模式下运行(没有进度或错误消息)
  • -o /dev/null:将输出重定向到 /dev/null(丢弃它)
  • -w "...":显示带有时间信息的格式化输出

你应该看到类似这样的输出:

Connect: 0.052s
Total: 0.157s

这告诉你建立连接所需的时间以及请求完成的总时间。

测试域名解析

有时,连通性问题源于 DNS 问题。要测试域名是否可以解析为 IP 地址:

curl -v https://www.example.com 2>&1 | grep "Trying"

这使用 -v(详细)选项并过滤“Trying”行,该行显示正在连接的 IP 地址。你应该看到类似这样的输出:

* Trying 93.184.216.34:443...

这确认了域名已成功解析为 IP 地址。

创建一个简单的连接测试脚本

让我们创建一个简单的 shell 脚本来测试与多个站点的连通性。打开一个文本编辑器:

nano connection_test.sh

将以下内容添加到文件中:

#!/bin/bash

echo "Testing server connectivity..."

for site in google.com example.com github.com nonexistent-site.xyz; do
  echo -n "Testing $site: "

  ## Use curl with a 5-second timeout
  status_code=$(curl -s -o /dev/null -w "%{http_code}" --connect-timeout 5 "https://$site" 2> /dev/null)

  if [ $? -eq 0 ] && [ "$status_code" -lt 400 ]; then
    echo "OK (Status: $status_code)"
  else
    echo "Failed (Status: $status_code)"
  fi
done

echo "Testing complete!"

Ctrl+O,然后 Enter 保存文件,并使用 Ctrl+X 退出。

使脚本可执行:

chmod +x connection_test.sh

运行脚本:

./connection_test.sh

你应该看到显示每个站点连通性状态的输出:

Testing server connectivity...
Testing google.com: OK (Status: 200)
Testing example.com: OK (Status: 200)
Testing github.com: OK (Status: 200)
Testing nonexistent-site.xyz: Failed (Status: 000)
Testing complete!

此脚本提供了一种快速检查与多个服务器连通性的方法。

使用 cURL 进行高级连通性测试

现在你已经了解了基本的连通性测试,让我们探索 cURL 更多的高级功能,这些功能可以帮助进行详细的故障排除和测试。

使用详细模式进行详细调试

详细模式(-v 选项)对于排除连通性问题非常有用,因为它显示了整个请求和响应过程:

curl -v https://example.com

输出将是全面的,显示 DNS 解析、TLS 握手、请求标头、响应标头等等:

*   Trying 93.184.216.34:443...
* Connected to example.com (93.184.216.34) port 443 (#0)
* ALPN: offers h2
* ALPN: offers http/1.1
* TLSv1.3 (OUT), TLS handshake, Client hello (1):
* TLSv1.3 (IN), TLS handshake, Server hello (2):
* TLSv1.3 (IN), TLS handshake, Encrypted Extensions (8):
* TLSv1.3 (IN), TLS handshake, Certificate (11):
* TLSv1.3 (IN), TLS handshake, CERT verify (15):
* TLSv1.3 (IN), TLS handshake, Finished (20):
* TLSv1.3 (OUT), TLS handshake, Finished (20):
* SSL connection using TLSv1.3 / TLS_AES_256_GCM_SHA384
* ALPN: server accepted h2
* Server certificate:
*  subject: C=US; ST=California; L=Los Angeles; O=Internet Corporation for Assigned Names and Numbers; CN=www.example.org
*  start date: Nov 24 00:00:00 2022 GMT
*  expire date: Nov 24 23:59:59 2023 GMT
*  subjectAltName: host "example.com" matched cert's "example.com"
*  issuer: C=US; O=DigiCert Inc; CN=DigiCert TLS RSA SHA256 2020 CA1
*  SSL certificate verify ok.
* using HTTP/2
* h2 [:method: GET]
* h2 [:path: /]
* h2 [:scheme: https]
* h2 [:authority: example.com]
* h2 [user-agent: curl/7.81.0]
* h2 [accept: */*]
* Using Stream ID: 1
> GET / HTTP/2
> Host: example.com
> user-agent: curl/7.81.0
> accept: */*
>
* TLSv1.3 (IN), TLS handshake, Newsession Ticket (4):
* Connection state changed (MAX_CONCURRENT_STREAMS == 100)!
< HTTP/2 200
< age: 587269
< cache-control: max-age=604800
< content-type: text/html; charset=UTF-8
< date: Tue, 28 Mar 2023 12:40:01 GMT
< etag: "3147526947+ident"
< expires: Tue, 04 Apr 2023 12:40:01 GMT
< last-modified: Thu, 17 Oct 2019 07:18:26 GMT
< server: ECS (nyb/1D2B)
< vary: Accept-Encoding
< x-cache: HIT
< content-length: 1256
<
<!doctype html>
<html>
<head>
    <title>Example Domain</title>
    <!-- More HTML content -->
</head>
<body>
    <div>
        <h1>Example Domain</h1>
        <p>This domain is for use in illustrative examples in documents...</p>
        <!-- More content -->
    </div>
</body>
</html>
* Connection #0 to host example.com left intact

这种详细的输出可以帮助你确定连接可能失败的确切位置。

测试不同的 HTTP 方法

让我们测试一个 POST 请求到测试 API 端点:

curl -X POST -d "name=test&email=test@example.com" https://httpbin.org/post

此命令:

  • -X POST:指定一个 POST 请求
  • -d "name=test&email=test@example.com":在请求中发送表单数据

你应该收到一个 JSON 响应,显示你提交的数据:

{
  "args": {},
  "data": "",
  "files": {},
  "form": {
    "email": "test@example.com",
    "name": "test"
  },
  "headers": {
    "Accept": "*/*",
    "Content-Length": "32",
    "Content-Type": "application/x-www-form-urlencoded",
    "Host": "httpbin.org",
    "User-Agent": "curl/7.81.0",
    "X-Amzn-Trace-Id": "Root=1-642295b1-0d2340ef34f2e8ea6270241a"
  },
  "json": null,
  "origin": "198.51.100.42",
  "url": "https://httpbin.org/post"
}

使用自定义标头进行测试

许多 API 需要特定的标头来进行身份验证或指定内容类型。让我们测试一下:

curl -H "User-Agent: MyCustomAgent" -H "Authorization: Bearer test-token" https://httpbin.org/headers

此命令:

  • -H "User-Agent: MyCustomAgent":设置自定义 User-Agent 标头
  • -H "Authorization: Bearer test-token":设置一个 Authorization 标头

响应将显示你的请求中发送的标头:

{
  "headers": {
    "Accept": "*/*",
    "Authorization": "Bearer test-token",
    "Host": "httpbin.org",
    "User-Agent": "MyCustomAgent",
    "X-Amzn-Trace-Id": "Root=1-642295c3-73cac0a73b34b1c93a8ce520"
  }
}

测试不同端点的响应时间

让我们创建一个脚本来比较不同服务器的响应时间:

nano response_time.sh

添加以下内容:

#!/bin/bash

echo "Testing response times..."

for site in google.com bing.com baidu.com duckduckgo.com yahoo.com; do
  echo -n "$site: "
  curl -s -o /dev/null -w "%{time_total}s" "https://$site"
  echo ""
done

echo "Testing complete!"

保存文件并使其可执行:

chmod +x response_time.sh

运行脚本:

./response_time.sh

输出将显示每个站点的响应时间:

Testing response times...
google.com: 0.187s
bing.com: 0.232s
baidu.com: 0.412s
duckduckgo.com: 0.298s
yahoo.com: 0.342s
Testing complete!

这对于比较不同服务器的性能或随时间监控服务器的性能很有用。

测试到特定端口的 TCP 连通性

有时你需要测试服务器上是否打开了特定端口。cURL 也可以用于此目的:

curl -v telnet://example.com:80

如果端口已打开,你将看到一条成功的连接消息:

* Trying 93.184.216.34:80...
* Connected to example.com (93.184.216.34) port 80 (#0)

Ctrl+C 终止连接。

同样,你可以测试安全连接:

curl -v https://example.com:443

详细输出将显示连接是否成功,或者是否有任何问题。

创建一个全面的服务器监控工具

现在你已经学习了各种用于连通性测试的 cURL 技术,让我们构建一个更全面的服务器监控工具,该工具结合了这些技术。

全面的服务器监控脚本

创建一个新的脚本文件:

nano server_monitor.sh

添加以下内容:

#!/bin/bash

## Server Monitoring Script
## This script checks the availability and performance of specified servers

## Define colors for output
GREEN='\033[0;32m'
RED='\033[0;31m'
YELLOW='\033[0;33m'
NC='\033[0m' ## No Color

## Function to check server status
check_server() {
  local url=$1
  local timeout=5

  echo -e "\n${YELLOW}Testing $url:${NC}"

  ## Test connection and get status code
  status_code=$(curl -s -o /dev/null -w "%{http_code}" --connect-timeout $timeout "$url" 2> /dev/null)

  if [ "$status_code" -eq 200 ]; then
    echo -e "${GREEN}✓ Status: $status_code (OK)${NC}"
  elif [ "$status_code" -ge 100 ] && [ "$status_code" -lt 400 ]; then
    echo -e "${GREEN}✓ Status: $status_code (Success/Redirect)${NC}"
  elif [ "$status_code" -ge 400 ] && [ "$status_code" -lt 500 ]; then
    echo -e "${RED}✗ Status: $status_code (Client Error)${NC}"
  elif [ "$status_code" -ge 500 ]; then
    echo -e "${RED}✗ Status: $status_code (Server Error)${NC}"
  else
    echo -e "${RED}✗ Status: Connection failed${NC}"
  fi

  ## Measure response time if connection successful
  if [ "$status_code" -gt 0 ]; then
    response_time=$(curl -s -o /dev/null -w "%{time_total}" --connect-timeout $timeout "$url" 2> /dev/null)
    echo -e "• Response time: ${response_time}s"

    ## Get server headers
    echo "• Server headers:"
    curl -s -I --connect-timeout $timeout "$url" | grep -E 'Server:|Content-Type:|Date:' | sed 's/^/  /'
  fi
}

## Main function
main() {
  echo -e "${YELLOW}===== Server Connectivity Monitor =====${NC}"
  echo "Started at: $(date)"

  ## List of servers to monitor
  servers=(
    "https://www.google.com"
    "https://www.github.com"
    "https://www.example.com"
    "https://httpbin.org/status/404" ## This will return a 404 status
    "https://httpbin.org/status/500" ## This will return a 500 status
  )

  ## Check each server
  for server in "${servers[@]}"; do
    check_server "$server"
  done

  echo -e "\n${YELLOW}===== Monitoring Complete =====${NC}"
  echo "Finished at: $(date)"
}

## Run the main function
main

保存文件并使其可执行:

chmod +x server_monitor.sh

运行脚本:

./server_monitor.sh

输出将提供每个服务器的全面状态概述:

===== Server Connectivity Monitor =====
Started at: Tue Mar 28 13:15:01 UTC 2023

Testing https://www.google.com:
✓ Status: 200 (OK)
• Response time: 0.186s
• Server headers:
  Date: Tue, 28 Mar 2023 13:15:02 GMT
  Content-Type: text/html; charset=ISO-8859-1
  Server: gws

Testing https://www.github.com:
✓ Status: 200 (OK)
• Response time: 0.247s
• Server headers:
  Server: GitHub.com
  Date: Tue, 28 Mar 2023 13:15:02 GMT
  Content-Type: text/html; charset=utf-8

Testing https://www.example.com:
✓ Status: 200 (OK)
• Response time: 0.132s
• Server headers:
  Content-Type: text/html; charset=UTF-8
  Date: Tue, 28 Mar 2023 13:15:03 GMT
  Server: ECS (nyb/1D2B)

Testing https://httpbin.org/status/404:
✗ Status: 404 (Client Error)
• Response time: 0.189s
• Server headers:
  Date: Tue, 28 Mar 2023 13:15:03 GMT
  Content-Type: text/html; charset=utf-8
  Server: gunicorn/19.9.0

Testing https://httpbin.org/status/500:
✗ Status: 500 (Server Error)
• Response time: 0.192s
• Server headers:
  Date: Tue, 28 Mar 2023 13:15:03 GMT
  Content-Type: text/html; charset=utf-8
  Server: gunicorn/19.9.0

===== Monitoring Complete =====
Finished at: Tue Mar 28 13:15:04 UTC 2023

安排定期连通性检查

要定期监控服务器,你可以设置一个 cron 作业。在真正的生产环境中,你可能会将此脚本添加到 crontab 中,以便定期运行。为了演示目的,让我们创建一个简单的包装脚本,该脚本以指定的持续时间每分钟运行一次监控:

nano scheduled_monitor.sh

添加以下内容:

#!/bin/bash

## Scheduled monitoring script
## This script runs the server_monitor.sh at regular intervals

## Check if duration parameter is provided
if [ $## -ne 1 ]; then
  echo "Usage: $0 <duration_in_minutes>"
  exit 1
fi

duration=$1
interval=60 ## seconds
iterations=$((duration * 60 / interval))

echo "Starting scheduled monitoring for $duration minutes..."
echo "Press Ctrl+C to stop monitoring"

for ((i = 1; i <= iterations; i++)); do
  echo -e "\n===== Run $i of $iterations ====="
  ./server_monitor.sh

  ## Don't sleep after the last iteration
  if [ $i -lt $iterations ]; then
    echo "Next check in $interval seconds..."
    sleep $interval
  fi
done

echo "Scheduled monitoring completed."

保存文件并使其可执行:

chmod +x scheduled_monitor.sh

运行脚本 2 分钟(你可以根据需要增加或减少):

./scheduled_monitor.sh 2

这将每分钟运行服务器监控脚本 2 分钟:

Starting scheduled monitoring for 2 minutes...
Press Ctrl+C to stop monitoring

===== Run 1 of 2 =====
===== Server Connectivity Monitor =====
...
(monitoring output)
...
Next check in 60 seconds...
(waits for 60 seconds)

===== Run 2 of 2 =====
===== Server Connectivity Monitor =====
...
(monitoring output)
...
Scheduled monitoring completed.

在生产环境中,你通常会设置一个 cron 作业,但此脚本提供了一种在本次实验练习期间执行计划监控的简单方法。

总结

在这个实验中,你探索了如何在 Linux 环境中使用 cURL 测试服务器连通性。从基础开始,你学习了如何发送简单的 HTTP 请求并将响应保存到文件中。然后,你深入研究了更复杂的操作,包括检查 HTTP 状态码、测量响应时间以及使用详细模式进行详细调试。

你创建了几个实用的脚本,这些脚本展示了 cURL 在服务器监控和连通性测试方面的强大功能:

  1. 一个基本的连接测试脚本,用于检查与多个服务器的连通性
  2. 一个响应时间比较脚本,用于测量和比较服务器性能
  3. 一个全面的服务器监控工具,提供有关服务器状态、响应时间和标头信息的详细信息
  4. 一个计划监控脚本,用于自动化定期连通性检查

这些工具和技术对于系统管理员、开发人员以及任何使用网络系统的人来说都非常宝贵。通过掌握 cURL,你现在拥有了一个强大的工具,可以在你的 Linux 环境中诊断和解决连通性问题。

当你继续使用 Linux 系统时,请记住 cURL 不仅对测试连通性有用,还可用于与 API 交互、下载文件以及自动化各种与网络相关的任务。你在本实验中获得的技能将为你未来更高级的网络操作和故障排除奠定基础。