小編公司自從導入雲端服務後,Curl 指令直接變成最常使用的指令之一,用來分析網頁行為及研究跳轉和參數等等超級好用,避免瀏覽器智慧跳轉等等功能問題。
但認真做了功課才發現Curl參數超級多,同時才發現自己只有使用到部分功能,先將常用的部分寫一些範例。
指令介紹
curl [options] [URL...]
-A/--user-agent <string> 設定使用者代理發送給伺服器
-b/--cookie <name=string/file> cookie字串或檔案讀取位置
-c/--cookie-jar <file> 操作結束後把cookie寫入到這個檔案中
-C/--continue-at <offset> 斷點續轉
-d/--data "data"攜帶 HTTP POST Data
-D/--dump-header <file> 把header資訊寫入到該檔案中
-e/--referer 來源網址
-f/--fail 連線失敗時不顯示http錯誤
-F/用來向主機上傳二進制文件,可以指定MIME 類型,也可以指定文件名
-H/--header 設定 request 裡所攜帶的 header
-i/--include 在 output 顯示 response 的 header
-k:指定跳过 SSL 檢測
-L:会让 HTTP 请求跟随服务器的重定向。curl 默认不跟随重定向
--limit-rate:用来限制 HTTP 请求和回应的带宽,模拟慢网速的环境
-o/--output 把輸出寫到該檔案中,等同於wget指令
-O/--remote-name 把輸出寫到該檔案中,保留遠端檔案的檔名
-r/--range <range> 檢索來自HTTP/1.1或FTP伺服器位元組範圍
--resolve HOST:PORT:ADDRESS 強制將 HOST:PORT 解析到指定的IP ADDRESS
-s/--silent 靜音模式。不輸出任何東西
-T/--upload-file <file> 上傳檔案
-u/--user <user[:password]> 設定伺服器的使用者和密碼
-v/--verbose 輸出更多的訊息方便 debug
-w/--write-out [format] 什麼輸出完成後
-x/--proxy <host[:port]> 在給定的埠上使用HTTP代理
-X/--request [GET|POST|PUT|DELETE|PATCH] 使用指定的 http method 來發出 http request
-#/--progress-bar 進度條顯示當前的傳送狀態
訪問網頁
第一步通是驗證訪問網站有無錯誤,首先使用的是 curl 不加上任何參數,先測試訪狀態再來檢查是否有任何問題。
要注意訪問指定port號時要確認http還是https是使用哪種。
#訪問 HTTPS 網頁
curl https://www.cjkuo.net
#訪問 HTTPS 特殊 port
curl https://www.cjkuo.net:8080/
#訪問 HTTP 網頁
curl http://www.cjkuo.net
#訪問 HTTP 特殊 port
curl http://www.cjkuo.net:8080/
-A 指定 User-Agent
網路安全不斷受到重視,會遇到某些網頁不給curl此類型的工具做連線,需要修改user-agent 來宣告改變瀏覽器,下方當執行指令時有指定時跟沒有指定時的執行差異比較。
當指定user-agent 是”Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.0.0 Safari/537.36″時,會看到user-agent 從 curl/7.81.0 變成 Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.0.0 Safari/537.36。
$ curl -v -A "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.0.0 Safari/537.36" https://google.com/
---省略----
> GET / HTTP/2
> Host: google.com
> user-agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.0.0 Safari/537.36
> accept: */*
>
* TLSv1---省略----
$ curl -v https://google.com/
---省略----
> GET / HTTP/2
> Host: google.com
> user-agent: curl/7.81.0
> accept: */*
>
* TLSv1---省略----
-c/-b 儲存及讀取Cookie
很多網站都會使用cookie 來做登入上的認證,或是訪問時辨認是否為正常的使用者此時就可以使用-c 來儲存 cookie ,-b來讀取 cookie。
curl -c cookie_file https://www.google.com/
#將請求時產生的 cookie 資訊儲存至cookie_file
curl -b cookie_file https://www.google.com/
#發出請求時將 cookie_file 中的資訊帶入至請求中
有的時候需要同時讀取cookie 資訊及寫入cookie 資訊,這時就需要同時下兩個指令。
curl -b cookie_file -c cookie_file https://www.google.com/
#訪問時將 cookie_file 中的資訊帶入至請求中,並將完成後的cookie 資訊寫入 cookie_file 檔案中。
-e 帶入來源網址 referer
部分server為了要避免盜連問題會確認引用源是否來自同一個站,此時就要欺騙服務器的檢查機制來取得相關資源。
$ curl -v -e "www.facebook.com" https://google.com/
---- 省略 ----
> GET / HTTP/2
> Host: google.com
> user-agent: curl/7.81.0
> accept: */*
> referer: www.facebook.com
# 帶入訪問來源 "www.facebook.com"
>
---- 省略 ----
當為了某些連結是必須透過301或302跳轉過去的,這時會使用 auto 參數來讓訪問更加擬真。
$ curl -L -v -e ";auto" https://google.com/
---- 省略 ----
< HTTP/2 301
< location: https://www.google.com/
#server 回應跳轉
---- 省略 ----
> GET / HTTP/2
> Host: www.google.com
> user-agent: curl/7.81.0
> accept: */*
> referer: https://google.com/
#使用 auto 會自動帶-L 之前跳轉的頁面資訊
---- 省略 ----
-o/-O 下載檔案,-C中斷續載
透過下載檔案測試站點上傳速度、本地的下載速度或將網路資源保存在電腦中,可以使用-o 這個參數,但要注意執行時大小寫有不同。
小寫的-o 代表下載檔案並重新命名,下載風景圖的範例:
curl -o city_bridge https://cdn.stocksnap.io/img-thumbs/960w/city-bridge_KSM9UIBTQ9.jpg
大寫的-O 代表下載檔案並使用原始圖檔的名稱(city-bridge_KSM9UIBTQ9.jpg),下載風景圖的範例:
curl -O https://cdn.stocksnap.io/img-thumbs/960w/city-bridge_KSM9UIBTQ9.jpg
檔案下載到中斷時不用整個檔案重新下載,可利用-C 的指令重新續傳下載。
curl -C -O https://cdn.stocksnap.io/img-thumbs/960w/city-bridge_KSM9UIBTQ9.jpg
limit-rate 限制傳輸速度
要測試下載是否正常又不想佔滿網路頻寬,需限制 curl 的資料傳輸速度,使用 –limit-rate 參數來指定傳輸速度的上限。
這裡使用 --limit-rate
參數所指定的傳輸速度上限值,可用的單位有 KB(K
或 k
)、MB(M
或 m
)、GB(G
或 g
),例如 100k
、10M
、2G
等,但都是大約限速不會剛剛好的就卡死在某一個數字上喔。
$curl --limit-rate 100k -O https://cdn.stocksnap.io/img-thumbs/960w/city-bridge_KSM9UIBTQ9.jpg
-L 跟隨跳轉
預設情形下 Curl 執行時不會跟隨301或302跳轉,遇到頁面會需要跳轉此功能請加上 -L,例如直接使用 curl 訪問 http://google.com/ 在下方範例就不會跳轉。
cjk@cjk:~$ curl http://google.com/
<HTML><HEAD><meta http-equiv="content-type" content="text/html;charset=utf-8">
<TITLE>301 Moved</TITLE></HEAD><BODY>
<H1>301 Moved</H1>
The document has moved
<A HREF="http://www.google.com/">here</A>.
</BODY></HTML>
-i/-I 顯示 response 的 header
在做驗證的時候除了要看到網頁內容,更重要的是要知道連線中每個細節有甚麼不一樣。此時會多看 Server 回應的header及內容,來判別目前異常的現象或是瀏覽器行為。
大小寫的i在輸出內容有差異,最主要不會顯示網頁內容,除非必要不然在使用上我通常使用大I可以有減少輸出內容,來減少閱讀上的疲憊感。
$ curl -i http://google.com/
HTTP/1.1 301 Moved Permanently
Location: http://www.google.com/
Content-Type: text/html; charset=UTF-8
Date: Sun, 17 Jul 2022 07:14:22 GMT
Expires: Tue, 16 Aug 2022 07:14:22 GMT
Cache-Control: public, max-age=2592000
Server: gws
Content-Length: 219
X-XSS-Protection: 0
X-Frame-Options: SAMEORIGIN
<HTML><HEAD><meta http-equiv="content-type" content="text/html;charset=utf-8">
<TITLE>301 Moved</TITLE></HEAD><BODY>
<H1>301 Moved</H1>
The document has moved
<A HREF="http://www.google.com/">here</A>.
</BODY></HTML>
$ curl -I http://google.com/
HTTP/1.1 301 Moved Permanently
Location: http://www.google.com/
Content-Type: text/html; charset=UTF-8
Date: Sun, 17 Jul 2022 07:18:26 GMT
Expires: Tue, 16 Aug 2022 07:18:26 GMT
Cache-Control: public, max-age=2592000
Server: gws
Content-Length: 219
X-XSS-Protection: 0
X-Frame-Options: SAMEORIGIN
resolve 強制解析Host 為指定IP
需要針對某些網站或是主機做測試時都需要更改hosts檔案,可直接使用resolve參數來強制將host解析成需要的IP。
$ curl --resolve www.google.com:443:142.251.35.164 -v https://www.google.com
* Added www.google.com:443:142.251.35.164 to DNS cache
#將 www.google.com 解析為142.251.35.164 新增至 DNS 快取中
* Hostname www.google.com was found in DNS cache
#解析Hostname www.google.com 時有在DNS快取中找到,優先使用快取紀錄。
* Trying 142.251.35.164:443...
* Connected to www.google.com (142.251.35.164) port 443 (#0)
-v 輸出完整訊息
-v 這個功能主要是用來除錯或完整顯示整個連線過程的內容,會包含 SSL 握手資訊及 request 裡所攜帶的 header。當使用-i/-I 這個參數已經無法判別,就使用-v看更詳細的輸出來理解過程中到底是段在哪裡排除。
另外有寫一篇利用-v 來判別錯誤發生在哪一個可能的範圍,請參考文章”Linux curl -v 快速判別無法訪問服務問題點在哪裡?“。
$ curl -v https://google.com/
* Trying 172.217.160.78:443...
* Connected to google.com (172.217.160.78) port 443 (#0)
* ALPN, offering h2
* ALPN, offering http/1.1
* CAfile: /etc/ssl/certs/ca-certificates.crt
* CApath: /etc/ssl/certs
* TLSv1.0 (OUT), TLS header, Certificate Status (22):
* TLSv1.3 (OUT), TLS handshake, Client hello (1):
* TLSv1.2 (IN), TLS header, Certificate Status (22):
* TLSv1.3 (IN), TLS handshake, Server hello (2):
* TLSv1.2 (IN), TLS header, Finished (20):
* TLSv1.2 (IN), TLS header, Supplemental data (23):
* 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.2 (OUT), TLS header, Finished (20):
* TLSv1.3 (OUT), TLS change cipher, Change cipher spec (1):
* TLSv1.2 (OUT), TLS header, Supplemental data (23):
* TLSv1.3 (OUT), TLS handshake, Finished (20):
* SSL connection using TLSv1.3 / TLS_AES_256_GCM_SHA384
* ALPN, server accepted to use h2
* Server certificate:
* subject: CN=*.google.com
* start date: Jun 27 08:17:39 2022 GMT
* expire date: Sep 19 08:17:38 2022 GMT
* subjectAltName: host "google.com" matched cert's "google.com"
* issuer: C=US; O=Google Trust Services LLC; CN=GTS CA 1C3
* SSL certificate verify ok.
* Using HTTP2, server supports multiplexing
* Connection state changed (HTTP/2 confirmed)
* Copying HTTP/2 data in stream buffer to connection buffer after upgrade: len=0
* TLSv1.2 (OUT), TLS header, Supplemental data (23):
* TLSv1.2 (OUT), TLS header, Supplemental data (23):
* TLSv1.2 (OUT), TLS header, Supplemental data (23):
* Using Stream ID: 1 (easy handle 0x55baeda86e80)
* TLSv1.2 (OUT), TLS header, Supplemental data (23):
> GET / HTTP/2
> Host: google.com
> user-agent: curl/7.81.0
> accept: */*
>
* TLSv1.2 (IN), TLS header, Supplemental data (23):
* TLSv1.3 (IN), TLS handshake, Newsession Ticket (4):
* TLSv1.3 (IN), TLS handshake, Newsession Ticket (4):
* old SSL session ID is stale, removing
* TLSv1.2 (IN), TLS header, Supplemental data (23):
* TLSv1.2 (OUT), TLS header, Supplemental data (23):
* TLSv1.2 (IN), TLS header, Supplemental data (23):
* TLSv1.2 (IN), TLS header, Supplemental data (23):
< HTTP/2 301
< location: https://www.google.com/
< content-type: text/html; charset=UTF-8
< date: Sun, 17 Jul 2022 07:26:16 GMT
< expires: Tue, 16 Aug 2022 07:26:16 GMT
< cache-control: public, max-age=2592000
< server: gws
< content-length: 220
< x-xss-protection: 0
< x-frame-options: SAMEORIGIN
< alt-svc: h3=":443"; ma=2592000,h3-29=":443"; ma=2592000,h3-Q050=":443"; ma=2592000,h3-Q046=":443"; ma=2592000,h3-Q043=":443"; ma=2592000,quic=":443"; ma=2592000; v="46,43"
<
* TLSv1.2 (IN), TLS header, Supplemental data (23):
<HTML><HEAD><meta http-equiv="content-type" content="text/html;charset=utf-8">
<TITLE>301 Moved</TITLE></HEAD><BODY>
<H1>301 Moved</H1>
The document has moved
<A HREF="https://www.google.com/">here</A>.
</BODY></HTML>
* TLSv1.2 (IN), TLS header, Supplemental data (23):
* Connection #0 to host google.com left intact
-V 檢查 Curl 版本
最後不要忘了檢查 curl版本,偶而在比較舊的版本中會有些bug或是不支援,老司機通常都是死在這種小細節上。
$ curl -V
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.12
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
-o/-O 下載檔案,-C中斷續載 部分的 code block標題複製貼上忘記改了