linux 上如何测试一个网页能不能用
今天有个同事说, 她在生产环境某个container里面的代码访问某个网页页面, 返回的结果不是期望的. 能不能一起看看到底是哪里出错了? 竟然有这么有趣的问题, 于是满口答应, 一块去探个究竟.
当然, 第一步就是去重现一下场景. 于是kubectl exec <pod_id> -n <ns> bash
登录container, 想着使用curl去模拟访问, 结果很沮丧. 为啥, 这个 container 真干净, 上面的代码是Java写的, 只有jdk, 没有curl, 没有wget, 让我怎么复现? 难道要自己写个Java Client, 打包编译, 然后去复现?
除了使用Java代码去实现访问网页http请求, 其他真没办法了吗? 让我们整理一下在Linux上常见的使用工具访问web网页的办法.
使用 curl
curl 是最方便的测试网页访问的工具, 很多Linux发布版都带curl, 支持很多协议.
$ curl -vvv 'https://www.tianxiaohui.com/index.php/about.html'
使用 wget
wget 支持 http, https, ftp, ftps这些协议去访问某个页面或资源, 也很方便使用, 很多Linux 发行版也自带.
$ wget 'https://www.tianxiaohui.com/index.php/about.html'
使用 netcat | ncat
netcat 是 GNU 一个网络实用工具, 不过根据官方网站在2004年发完0.7.1版本之后, 就没更新过了, 我发现我 Ubuntu 使用的是openBSD 版本的(https://packages.debian.org/sid/netcat-openbsd). 它最常用的是打开端口, 建立连接, 至于http协议, 那要自己去实现. 实现http协议还好, 如果实现证书认证https, 那可是有点难度.
所以, 你看我只能拿到一个400的错误. 不过要是访问非https的, 还是很可行的.
$ printf “GET /index.php/about.html HTTP/1.0\r\nHost: www.tianxiaohui.com\r\n\r\n” | nc www.tianxiaohui.com 443
F<html><head><title>400 Bad Request</title></head><body>
<h2>HTTPS is required</h2>
<p>This is an SSL protected page, please use the HTTPS scheme instead of the plain HTTP scheme to access this URL.<br />
<blockquote>Hint: The URL should starts with <b>https</b>://</blockquote> </p>
<hr />
Powered By LiteSpeed Web Server<br />
<a href='http://www.litespeedtech.com'><i>http://www.litespeedtech.com</i></a>
</body></html>
有人称它为网络debug的瑞士军刀, 没有继续开发, 是不是可惜了. 所以鼎鼎大名的nmap工具下面, 发扬了netcat的功能, 开了一ncat, 比netcat 更好用. 还支持 ssl. 那必须测试一把
$ printf "GET /index.php/about.html HTTP/1.0\r\nHost: www.tianxiaohui.com\r\n\r\n" | ncat -v --ssl www.tianxiaohui.com 443
Ncat: Version 7.80 ( https://nmap.org/ncat )
Ncat: SSL connection to 154.213.16.200:443.
Ncat: SHA-1 fingerprint: 8461 369A 0DE4 7401 AE26 4259 B0C2 CC9F FE0B 66F5
HTTP/1.0 200 OK
Connection: close
content-type: text/html; charset=UTF-8
x-pingback: https://www.tianxiaohui.com/index.php/action/xmlrpc
date: Thu, 16 Feb 2023 15:08:37 GMT
server: LiteSpeed
vary: User-Agent,User-Agent
<!DOCTYPE HTML>
<html class="no-js">
<head>
...省略
</html>
完美拿到数据
使用 openssl
openssl 是一个开源的, 通用的加密安全的工具软件, 很多Linux 发行版都带了它, 使用它进行网页访问, 也不在话下.
$printf "GET /index.php/about.html HTTP/1.0\r\nHost: www.tianxiaohui.com\r\n\r\n" | openssl s_client -quiet -state -connect www.tianxiaohui.com:443
SSL_connect:before SSL initialization
SSL_connect:SSLv3/TLS write client hello
SSL_connect:SSLv3/TLS write client hello
SSL_connect:SSLv3/TLS read server hello
SSL_connect:TLSv1.3 read encrypted extensions
depth=2 C = US, O = Internet Security Research Group, CN = ISRG Root X1
verify return:1
depth=1 C = US, O = Let's Encrypt, CN = R3
verify return:1
depth=0 CN = www.tianxiaohui.com
verify return:1
SSL_connect:SSLv3/TLS read server certificate
SSL_connect:TLSv1.3 read server certificate verify
SSL_connect:SSLv3/TLS read finished
SSL_connect:SSLv3/TLS write change cipher spec
SSL_connect:SSLv3/TLS write finished
HTTP/1.0 200 OK
仅仅使用 bash, 你没看错
如果你的container里面非常干净, 上面的软件全没有, 但恰巧你安装的是bash, 那么这个任务还是能完成. 仔细看:
supra@suprabox:~$ exec 4<>/dev/tcp/www.tianxiaohui.com/443
supra@suprabox:~$ echo -e "GET /index.php/about.html HTTP/1.0\r\nHost: www.tianxiaohui.com\r\n\r\n" >&4
supra@suprabox:~$ cat <&4
<html><head><title>400 Bad Request</title></head><body>
<h2>HTTPS is required</h2>
<p>This is an SSL protected page, please use the HTTPS scheme instead of the plain HTTP scheme to access this URL.<br />
<blockquote>Hint: The URL should starts with <b>https</b>://</blockquote> </p>
<hr />
Powered By LiteSpeed Web Server<br />
<a href='http://www.litespeedtech.com'><i>http://www.litespeedtech.com</i></a>
</body></html>
虽然, 能拿到结果, 但是没有ssl协商, 所以网站只给了一个400. 所以 bash 这种方式, 对于https只能验证连接成功, 不能验证拿到的结果.
那么我们就拿一个http的网站来练习一下, 可是如今到哪里去找一个还支持http的网站呢, 哈哈, 还真找到一个. 如下:
supra@suprabox:~$ exec 5<>/dev/tcp/www.henu.edu.cn/80
supra@suprabox:~$ echo -e "GET /index.htm HTTP/1.0\r\nHost: www.henu.edu.cn\r\n\r\n" >&5
supra@suprabox:~$ less <&5
完美拿到结果, 自己处理ssl 太难了, 不过对于仅仅http, 还是很管用的.
对于上面3步的解释:
- /dev/protocol/host/port 是bash的一个重定向文件, 它帮你建立一个连接, 协议可以是tcp或udp, host可以是主机名或ip, 所以第一行通过exec建立一个文件描述符是5的重定向.
- 第二步是把 http 协议的request 发送到这个连接
- 第三步读出返回的结果网页.
总结
上面的很多工具都很好用, 有些还支持设置代理, 设置timeout 等, 据有相当丰富的功能. 在container 里面受限的情况下, 还有哪些好用的网页测试工具? 当然, 你说我container 里面有 python, 有 perl, wow, 那你太幸福了.