如何使用 Curl 访问不同端口

LinuxBeginner
立即练习

介绍

Curl 是一个强大的命令行工具,允许你使用各种协议传输数据,包括 HTTP、FTP 和 SFTP。在本教程中,你将学习如何使用 Curl 访问服务器或网络上的不同端口,从而能够排查连接问题并测试端口可用性。

这个实践实验将指导你完成基本的和高级的 Curl 命令,用于端口访问,帮助你理解网络服务如何在不同的端口上运行。通过完成这个实验,你将能够自信地使用 Curl 与在各种端口上运行的服务进行交互。

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

Curl 入门

Curl,代表“客户端 URL”(Client URL),是一个用于向服务器传输或从服务器接收数据的命令行工具。它支持多种协议,包括 HTTP、HTTPS、FTP、SFTP 等等。在深入研究特定于端口的操作之前,让我们确保你理解 Curl 的基本用法。

基本 Curl 命令

打开你的终端,输入以下命令来检查你的系统上是否安装了 Curl:

curl --version

你应该看到类似这样的输出,显示 Curl 的版本和支持的功能:

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 https://example.com

此命令下载 example.com 的 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 HTML content -->
    </div>
  </body>
</html>

理解 HTTP 端口

Web 服务器通常在特定的端口上运行:

  • 端口 80 用于 HTTP(未加密)
  • 端口 443 用于 HTTPS(已加密)

当你访问一个网站时,如果没有指定端口,你的浏览器会自动使用这些默认端口。但是,使用 Curl,你可以明确指定要连接的端口。

让我们尝试在标准 HTTP 端口(端口 80)上访问一个网站:

curl http://example.com:80

输出应该与你之前的 Curl 命令类似,因为端口 80 是 HTTP 的默认端口。

现在,尝试在 HTTPS 端口(端口 443)上访问同一个网站:

curl https://example.com:443

同样,输出应该类似,因为端口 443 是 HTTPS 的默认端口。

在这些例子中,我们使用 protocol://domain:port 的格式在 URL 中明确指定了端口。当使用非标准端口上的服务时,这种语法至关重要。

使用 Curl 与不同的端口

现在你已经了解了 Curl 的基础知识和端口规范,让我们探索如何与不同的端口交互。

访问非标准 Web 端口

Web 服务器可以在 80 和 443 之外的端口上运行。为了进行测试,让我们使用 Python 内置的 HTTP 服务器在端口 8000 上设置一个简单的 Web 服务器。

首先,创建一个要提供服务的简单 HTML 文件:

echo "<html><body><h1>Hello from port 8000!</h1></body></html>" > ~/project/test.html

现在,导航到包含该文件的目录,并在端口 8000 上启动一个简单的 HTTP 服务器:

cd ~/project
python3 -m http.server 8000 &

命令末尾的 & 在后台运行服务器。你应该看到类似这样的输出:

Serving HTTP on 0.0.0.0 port 8000 (http://0.0.0.0:8000/) ...

现在,使用 Curl 访问端口 8000 上的这个服务器:

curl http://localhost:8000/test.html

你应该看到我们创建的 HTML 内容:

<html>
  <body>
    <h1>Hello from port 8000!</h1>
  </body>
</html>

当我们完成服务器的使用后,我们可以通过找到它的进程 ID 并将其终止来停止它:

ps aux | grep "python3 -m http.server"

这将显示类似以下的输出:

labex     1234  0.0  0.1 235368 12312 pts/0    S    10:00   0:00 python3 -m http.server 8000
labex     1235  0.0  0.0  12345  1234 pts/0    S+   10:01   0:00 grep --color=auto python3 -m http.server

注意第二列中的进程 ID(PID)(在本例中为 1234),然后终止该进程:

kill $(pgrep -f "python3 -m http.server")

使用不同的 HTTP 方法

Curl 允许你使用 -X 标志指定不同的 HTTP 方法。让我们尝试一个 POST 请求:

curl -X POST http://example.com

这会将一个 POST 请求发送到 example.com。大多数网站将回复一条消息,表明它们期望 POST 请求的不同数据。

向请求添加标头

在使用 API 或特定服务时,你通常需要发送自定义标头。你可以使用 -H 标志来执行此操作:

curl -H "Content-Type: application/json" http://example.com

这会发送一个带有 JSON 内容类型标头的请求。响应将取决于服务器如何处理此标头。

查看响应标头

要查看响应标头以及内容,请使用 -i 标志:

curl -i http://example.com

这将显示类似以下的输出:

HTTP/1.1 200 OK
Content-Encoding: gzip
Accept-Ranges: bytes
Age: 558039
Cache-Control: max-age=604800
Content-Type: text/html; charset=UTF-8
Date: Wed, 07 Jun 2023 12:34:56 GMT
Etag: "3147526947+gzip"
Expires: Wed, 14 Jun 2023 12:34:56 GMT
Last-Modified: Thu, 17 Oct 2019 07:18:26 GMT
Server: ECS (dcb/7F5B)
Vary: Accept-Encoding
X-Cache: HIT
Content-Length: 1256

<!doctype html>
<html>
<head>
    <title>Example Domain</title>
    <!-- More HTML content -->
</head>
<!-- More HTML content -->
</html>

标头提供了关于服务器、内容类型、缓存策略等方面的有价值的信息。

使用 Curl 进行高级端口访问

现在你已经了解了使用 Curl 与不同端口的基础知识,让我们探索更多用于端口访问和测试的高级技术。

测试端口可用性

Curl 可用于检查服务器上是否打开了特定端口。当端口打开时,Curl 将尝试建立连接并可能接收数据。当端口关闭时,Curl 将报告错误。

让我们测试一些常用端口:

## 测试端口 80 (HTTP) 是否打开
curl -s -o /dev/null -w "%{http_code}\n" http://example.com:80

此命令将显示 HTTP 状态码(如果端口打开且服务器响应正确,通常为 200)。-s 标志使 Curl 保持静默,-o /dev/null 将输出重定向到无处,而 -w "%{http_code}\n" 仅打印 HTTP 状态码。

让我们再试几个端口:

## 测试端口 443 (HTTPS) 是否打开
curl -s -o /dev/null -w "%{http_code}\n" https://example.com:443

这应该返回 200 或另一个 HTTP 状态码,表明端口 443 已打开。

现在,让我们测试一个可能已关闭的端口:

## 测试端口 81 (不常用) 是否打开
curl -s --connect-timeout 5 http://example.com:81

此命令可能会失败,并显示类似以下的错误消息:

curl: (7) Failed to connect to example.com port 81: Connection refused

或者它可能会在 5 秒后超时(如 --connect-timeout 指定的那样):

curl: (28) Connection timed out after 5001 milliseconds

访问 FTP 服务器

Curl 支持多种协议,包括 FTP。让我们看看如何访问 FTP 服务器:

curl ftp://ftp.gnu.org/gnu/

此命令列出 ftp.gnu.org 目录的内容。输出可能如下所示:

drwxr-xr-x    8 1003     1003         4096 Dec 16  2020 0ad
drwxr-sr-x    5 1003     1003         4096 Nov 09  2020 8sync
drwxr-xr-x    2 1003     1003         4096 Jun 05  2015 GNUinfo
drwxr-xr-x    3 1003     1003         4096 Jan 23  2022 GNUnet
...

创建一个简单的端口扫描器

让我们创建一个简单的 Bash 脚本来扫描服务器上的一系列端口。在你的项目目录中创建一个名为 port_scanner.sh 的新文件:

nano ~/project/port_scanner.sh

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

#!/bin/bash

## 使用 curl 的简单端口扫描器
## 用法:./port_scanner.sh <hostname> <start_port> <end_port>

hostname=$1
start_port=$2
end_port=$3

echo "正在扫描 $hostname 上的端口 $start_port 到 $end_port..."
echo

for port in $(seq $start_port $end_port); do
  ## 尝试以短超时时间连接
  curl -s --connect-timeout 1 "$hostname:$port" > /dev/null

  ## 检查连接是否成功
  if [ $? -eq 0 ]; then
    echo "端口 $port 已打开"
  else
    echo "端口 $port 已关闭"
  fi
done

echo
echo "扫描完成!"

通过按 Ctrl+X,然后按 Y,然后按 Enter 来保存文件。

使脚本可执行:

chmod +x ~/project/port_scanner.sh

现在,运行脚本以扫描 example.com 上的端口 80-85:

~/project/port_scanner.sh example.com 80 85

输出将显示哪些端口已打开,哪些端口已关闭:

正在扫描 example.com 上的端口 80 到 85...

端口 80 已打开
端口 81 已关闭
端口 82 已关闭
端口 83 已关闭
端口 84 已关闭
端口 85 已关闭

扫描完成!

这个简单的脚本演示了如何将 Curl 用作基本的端口扫描工具。在实际应用场景中,你可能需要使用像 nmap 这样的专用工具来进行更全面的网络扫描,但这个例子展示了 Curl 的多功能性。

使用 HTTPS 和安全连接

在这一步中,我们将探讨如何将 Curl 与 HTTPS 一起使用,并处理各种与安全相关的选项。

了解 HTTPS 连接

HTTPS 连接使用 SSL/TLS 协议来保护数据传输。当你使用 Curl 连接到 HTTPS 站点时,它默认会验证服务器的 SSL 证书。

让我们尝试连接到一个安全的网站:

curl https://www.google.com

此命令连接到 Google 的 HTTPS 服务器并返回 HTML 内容。

处理 SSL 证书验证

有时,你可能需要连接到具有自签名或无效证书的服务器。在这种情况下,你可以使用 -k--insecure 选项来跳过证书验证:

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

即使无法验证证书,此命令也将连接到该站点。输出应该与之前的命令类似。

查看证书信息

要检查网站的 SSL 证书,请使用 -v(详细)选项:

curl -v https://www.google.com > /dev/null

此命令将显示有关 SSL 握手和证书的详细信息,同时将实际内容发送到 /dev/null。输出包括证书详细信息:

* Server certificate:
*  subject: CN=www.google.com
*  start date: ...
*  expire date: ...
*  subjectAltName: ...
*  issuer: CN=GTS CA 1C3; O=Google Trust Services LLC; C=US
*  SSL certificate verify ok.

使用特定的 TLS 版本

你可以使用 --tlsv1.X 选项指定要使用的 TLS 版本:

## 强制使用 TLS 1.2
curl --tlsv1.2 https://www.google.com > /dev/null

这确保 Curl 使用 TLS 1.2 进行连接。

安全地下载文件

Curl 可以从 HTTPS 来源下载文件。让我们使用 -o 选项下载一个文件并保存它:

curl -o ~/project/google_logo.png https://www.google.com/images/branding/googlelogo/1x/googlelogo_color_272x92dp.png

此命令下载 Google 的徽标并将其保存为项目目录中的 google_logo.png。检查文件是否存在:

ls -l ~/project/google_logo.png

你应该看到类似以下的输出:

-rw-r--r-- 1 labex labex 5969 Jun 7 12:34 /home/labex/project/google_logo.png

为 HTTPS 指定自定义标头

在使用安全 API 时,你通常需要包含身份验证标头。以下是如何操作:

curl -H "Authorization: Bearer your_token_here" https://api.example.com

如果你有实际的令牌,请将其替换为 your_token_here。否则,此命令可能会从服务器返回错误或未经授权的消息。

访问非标准端口上的 HTTPS

HTTPS 服务可以在 443 以外的端口上运行。要访问此类服务,请在 URL 中指定端口:

curl https://example.com:8443

此命令尝试连接到端口 8443 上的 HTTPS 服务。由于 example.com 在此端口上没有服务,你可能会看到一个错误:

curl: (7) Failed to connect to example.com port 8443: Connection refused

这表明 Curl 可以尝试使用任何协议连接到任何端口,这使其成为测试网络服务的通用工具。

创建一个综合的端口检查脚本

在最后一步中,我们将创建一个更复杂的脚本,该脚本使用 Curl 来检查目标服务器上的常见服务。

了解常见服务端口

不同的服务通常在标准端口上运行:

  • Web (HTTP):端口 80
  • 安全 Web (HTTPS):端口 443
  • FTP:端口 21
  • SSH:端口 22
  • SMTP (电子邮件):端口 25
  • DNS:端口 53
  • 数据库 (MySQL):端口 3306
  • 数据库 (PostgreSQL):端口 5432

让我们创建一个脚本,该脚本检查给定主机上的这些常见端口。

创建服务检查器脚本

在你的项目目录中创建一个名为 service_checker.sh 的新文件:

nano ~/project/service_checker.sh

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

#!/bin/bash

## 使用 curl 的服务检查器脚本
## 用法:./service_checker.sh <hostname>

hostname=$1

if [ -z "$hostname" ]; then
  echo "错误:请提供主机名。"
  echo "用法:./service_checker.sh <hostname>"
  exit 1
fi

echo "正在检查 $hostname 上的常见服务..."
echo

## 使用适当的协议检查端口的函数
check_port() {
  local port=$1
  local service=$2
  local protocol=$3
  local timeout=2

  echo -n "正在检查 $service (端口 $port):"

  ## 根据服务使用适当的协议
  if [ "$protocol" = "http" ]; then
    curl -s --connect-timeout $timeout "http://$hostname:$port" > /dev/null
  elif [ "$protocol" = "https" ]; then
    curl -s --connect-timeout $timeout "https://$hostname:$port" > /dev/null
  else
    ## 对于非 HTTP 协议,只需尝试连接到端口
    curl -s --connect-timeout $timeout "$hostname:$port" > /dev/null
  fi

  ## 检查结果
  if [ $? -eq 0 ]; then
    echo "可用"
  else
    echo "不可用"
  fi
}

## 检查常见服务
check_port 80 "Web 服务器 (HTTP)" "http"
check_port 443 "Web 服务器 (HTTPS)" "https"
check_port 21 "FTP 服务器" "tcp"
check_port 22 "SSH 服务器" "tcp"
check_port 25 "SMTP 服务器" "tcp"
check_port 53 "DNS 服务器" "tcp"
check_port 3306 "MySQL 数据库" "tcp"
check_port 5432 "PostgreSQL 数据库" "tcp"
check_port 8080 "备用 Web 服务器" "http"
check_port 8443 "备用安全 Web 服务器" "https"

echo
echo "服务检查完成!"

通过按 Ctrl+X,然后按 Y,然后按 Enter 来保存文件。

使脚本可执行:

chmod +x ~/project/service_checker.sh

运行服务检查器

现在,运行脚本以检查知名网站上的服务:

~/project/service_checker.sh example.com

你将看到类似以下的输出:

正在检查 example.com 上的常见服务...

正在检查 Web 服务器 (HTTP) (端口 80):可用
正在检查 Web 服务器 (HTTPS) (端口 443):可用
正在检查 FTP 服务器 (端口 21):不可用
正在检查 SSH 服务器 (端口 22):不可用
正在检查 SMTP 服务器 (端口 25):不可用
正在检查 DNS 服务器 (端口 53):不可用
正在检查 MySQL 数据库 (端口 3306):不可用
正在检查 PostgreSQL 数据库 (端口 5432):不可用
正在检查备用 Web 服务器 (端口 8080):不可用
正在检查备用安全 Web 服务器 (端口 8443):不可用

服务检查完成!

此输出显示 example.com 在端口 80 和 443 上运行 Web 服务器,但其他常见服务无法公开访问。

理解结果

我们脚本的结果提供了有价值的信息:

  1. 可用服务:这些端口已打开并响应请求,表明相应的服务正在运行且可访问。

  2. 不可用服务:这些端口可能:

    • 已关闭(没有服务运行)
    • 被防火墙过滤
    • 正在运行,但配置为不响应通用请求

此信息对于以下方面很有用:

  • 网络管理员检查服务可用性
  • 安全专业人员进行初步侦察
  • 开发人员验证其服务是否已正确配置

修改脚本

随意修改脚本以检查其他端口或服务。例如,你可以添加对以下内容的检查:

  • Redis (端口 6379)
  • MongoDB (端口 27017)
  • RDP (端口 3389)

要添加新的服务检查,只需使用 check_port 函数添加另一行:

check_port 6379 "Redis 数据库" "tcp"

这展示了 Curl 作为网络服务测试和监控工具的灵活性。

总结

在本教程中,你已经学习了如何使用 Curl 访问服务器和网络上的不同端口。你已经:

  • 学习了 Curl 的基础知识以及如何在 URL 中指定端口
  • 使用 Curl 与标准和非标准端口上的 Web 服务器交互
  • 探索了不同的 HTTP 方法和标头
  • 使用了 HTTPS 和安全连接
  • 创建了脚本来检查端口可用性和服务状态

这些技能对于网络故障排除、系统管理和安全测试非常有用。Curl 的多功能性使其成为你命令行工具包中的必备工具。

为了进行额外的练习,请尝试:

  • 使用 Curl 与 REST API 交互
  • 测试不同的连接超时和重试选项
  • 探索更多高级的 Curl 功能,如 Cookie、表单提交和代理设置
  • 使用其他协议和错误处理来增强服务检查器脚本

请记住,虽然 Curl 对于测试和基本扫描非常强大,但像 Nmap 这样的专业工具为专业用途提供了更全面的网络扫描功能。