介绍
Curl 是一个强大的命令行工具,允许你使用各种协议传输数据,包括 HTTP、FTP 和 SFTP。在本教程中,你将学习如何使用 Curl 访问服务器或网络上的不同端口,从而能够排查连接问题并测试端口可用性。
这个实践实验将指导你完成基本的和高级的 Curl 命令,用于端口访问,帮助你理解网络服务如何在不同的端口上运行。通过完成这个实验,你将能够自信地使用 Curl 与在各种端口上运行的服务进行交互。
Curl 是一个强大的命令行工具,允许你使用各种协议传输数据,包括 HTTP、FTP 和 SFTP。在本教程中,你将学习如何使用 Curl 访问服务器或网络上的不同端口,从而能够排查连接问题并测试端口可用性。
这个实践实验将指导你完成基本的和高级的 Curl 命令,用于端口访问,帮助你理解网络服务如何在不同的端口上运行。通过完成这个实验,你将能够自信地使用 Curl 与在各种端口上运行的服务进行交互。
Curl,代表“客户端 URL”(Client URL),是一个用于向服务器传输或从服务器接收数据的命令行工具。它支持多种协议,包括 HTTP、HTTPS、FTP、SFTP 等等。在深入研究特定于端口的操作之前,让我们确保你理解 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>
Web 服务器通常在特定的端口上运行:
当你访问一个网站时,如果没有指定端口,你的浏览器会自动使用这些默认端口。但是,使用 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 的基础知识和端口规范,让我们探索如何与不同的端口交互。
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")
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 将报告错误。
让我们测试一些常用端口:
## 测试端口 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
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 的多功能性。
在这一步中,我们将探讨如何将 Curl 与 HTTPS 一起使用,并处理各种与安全相关的选项。
HTTPS 连接使用 SSL/TLS 协议来保护数据传输。当你使用 Curl 连接到 HTTPS 站点时,它默认会验证服务器的 SSL 证书。
让我们尝试连接到一个安全的网站:
curl https://www.google.com
此命令连接到 Google 的 HTTPS 服务器并返回 HTML 内容。
有时,你可能需要连接到具有自签名或无效证书的服务器。在这种情况下,你可以使用 -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.
你可以使用 --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
在使用安全 API 时,你通常需要包含身份验证标头。以下是如何操作:
curl -H "Authorization: Bearer your_token_here" https://api.example.com
如果你有实际的令牌,请将其替换为 your_token_here。否则,此命令可能会从服务器返回错误或未经授权的消息。
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 来检查目标服务器上的常见服务。
不同的服务通常在标准端口上运行:
让我们创建一个脚本,该脚本检查给定主机上的这些常见端口。
在你的项目目录中创建一个名为 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 服务器,但其他常见服务无法公开访问。
我们脚本的结果提供了有价值的信息:
可用服务:这些端口已打开并响应请求,表明相应的服务正在运行且可访问。
不可用服务:这些端口可能:
此信息对于以下方面很有用:
随意修改脚本以检查其他端口或服务。例如,你可以添加对以下内容的检查:
要添加新的服务检查,只需使用 check_port 函数添加另一行:
check_port 6379 "Redis 数据库" "tcp"
这展示了 Curl 作为网络服务测试和监控工具的灵活性。
在本教程中,你已经学习了如何使用 Curl 访问服务器和网络上的不同端口。你已经:
这些技能对于网络故障排除、系统管理和安全测试非常有用。Curl 的多功能性使其成为你命令行工具包中的必备工具。
为了进行额外的练习,请尝试:
请记住,虽然 Curl 对于测试和基本扫描非常强大,但像 Nmap 这样的专业工具为专业用途提供了更全面的网络扫描功能。