使用 Netcat 模拟 HTTP 请求

Netcat 作为一款强大的网络工具,在开发及网络运维中可以发挥很大作用。本文说明一下使用 Netcat 进行 HTTP 调试的方式。其实对于 HTTP,专业的工具很多,更好用,本文旨在以 HTTP 协议为例,演示 Netcat 作为基于 Socket 传输层 的工具,如何对于应用层协议的访问进行调试。

一、使用工具

  • Netcat(nc)
  • http://httpbin.org

二、基本使用说明

1、非交互式访问

使用 GET 方法,访问 http://httpbin.org/ip 获取本机外网 IP

$ echo -e "GET /anything HTTP/1.0\r\nHost: httpbin.org\r\n\r\n" | nc httpbin.org 80

返回内容:

HTTP/1.1 200 OK
Connection: close
Server: gunicorn/19.9.0
Date: Wed, 28 Nov 2018 02:23:19 GMT
Content-Type: application/json
Content-Length: 248
Access-Control-Allow-Origin: *
Access-Control-Allow-Credentials: true
Via: 1.1 vegur

{
  "args": {},
  "data": "",
  "files": {},
  "form": {},
  "headers": {
    "Connection": "close",
    "Host": "httpbin.org"
  },
  "json": null,
  "method": "GET",
  "origin": "221.238.131.162",
  "url": "http://httpbin.org/anything"
}

说明:
这个例子,是通过 echo 命令,将 HTTP 的控制信息通过通道,传递给 nc
(1)传递的信息中,所有的回车换行,都以 \r\n 表示,对于最后一条控制语句,需要有两个连续的 \r\n
(2)在指定协议版本的时候,可以指定为 HTTP/1.0HTTP/1.1

  • HTTP/1.0 访问成功后,立即断开连接,效果等同于加上 Connection: close
  • HTTP/1.1 访问成功后,连接不会断开,效果等同于加上 Connection: keep-alived,以保证连接可以复用,这种方式只有 HTTP 1.1 才支持。需要使用 Connection: close 控制命令断开连接,或者 Ctrl + C 中止访问。
2、交互式访问
$ nc -c httpbin.org 80
GET /ip HTTP/1.0
Host: httpbin.org

返回内容:

HTTP/1.1 200 OK
Connection: close
Server: gunicorn/19.9.0
Date: Wed, 28 Nov 2018 02:36:52 GMT
Content-Type: application/json
Content-Length: 34
Access-Control-Allow-Origin: *
Access-Control-Allow-Credentials: true
Via: 1.1 vegur

{
  "origin": "221.238.131.162"
}

注意:
命令行中需要使用 -c 参数,以确保“回车换行”使用的是 \r\n

三、演示

1、GET 请求

向 http://httpbin.org/get 发送 GET 请求,传递参数 a=1,b=2

$ nc -c httpbin.org 80
GET /get?a=1&b=2 HTTP/1.0
Host: httpbin.org

返回内容:

HTTP/1.1 200 OK
Connection: close
Server: gunicorn/19.9.0
Date: Wed, 28 Nov 2018 02:39:34 GMT
Content-Type: application/json
Content-Length: 199
Access-Control-Allow-Origin: *
Access-Control-Allow-Credentials: true
Via: 1.1 vegur

{
  "args": {
    "a": "1",
    "b": "2"
  },
  "headers": {
    "Connection": "close",
    "Host": "httpbin.org"
  },
  "origin": "221.238.131.162",
  "url": "http://httpbin.org/get?a=1&b=2"
}
2、POST 请求

向 http://httpbin.org/post 发送 GET 请求,传递参数 a=1,b=2

$ nc -c httpbin.org 80
POST /post HTTP/1.0
Content-Type: application/x-www-form-urlencoded; charset=utf-8
Host: httpbin.org
Content-Length: 7

a=1&b=2

返回内容:

HTTP/1.1 200 OK
Connection: close
Server: gunicorn/19.9.0
Date: Wed, 28 Nov 2018 02:55:13 GMT
Content-Type: application/json
Content-Length: 356
Access-Control-Allow-Origin: *
Access-Control-Allow-Credentials: true
Via: 1.1 vegur

{
  "args": {},
  "data": "",
  "files": {},
  "form": {
    "a": "1",
    "b": "2"
  },
  "headers": {
    "Connection": "close",
    "Content-Length": "7",
    "Content-Type": "application/x-www-form-urlencoded; charset=utf-8",
    "Host": "httpbin.org"
  },
  "json": null,
  "origin": "221.238.131.162",
  "url": "http://httpbin.org/post"
}
3、通过 HTTP 代理服务器访问

通过标准的 HTTP 代理服务器访问,实际上是先将请求发送到代理服务器,再由代理服务器向实际目标转发请求。(隧道代理不是这种情况,隧道代理实际上是建立了一个通道,然后由客户端通过通道直接与目标服务器建立连接,所以 HTTP 隧道代理还可以代理 HTTPS 和其他基于 TCP 协议的应用。)

实验说明:

  • 目标服务:http://google.com
  • 代理服务:http://127.0.0.1:8016
$ nc -c 127.0.0.1 8016
GET http://google.com HTTP/1.0
Host: google.com

返回内容:

HTTP/1.1 301 Moved Permanently
Location: http://www.google.com/
Content-Type: text/html; charset=UTF-8
Date: Mon, 25 Nov 2019 06:45:56 GMT
Expires: Wed, 25 Dec 2019 06:45:56 GMT
Cache-Control: public, max-age=2592000
Server: gws
Content-Length: 219
X-XSS-Protection: 0
X-Frame-Options: SAMEORIGIN
X-Cache: MISS from slhk1.pages.googol.gl
X-Cache-Lookup: MISS from slhk1.pages.googol.gl:7228
Connection: close


301 Moved

301 Moved

The document has moved here.

注意两点:
1、通过 nc 连接时,命令行中指定连接的是代理服务器,而不是实际目标;
2、Request 的路径,需要写访问的完整目标,http://google.com,而不只是路径。

(完)

你可能感兴趣的:(使用 Netcat 模拟 HTTP 请求)