整合營銷服務商

          電腦端+手機端+微信端=數據同步管理

          免費咨詢熱線:

          工具-獲取HTTP接口服務的各個時間

          工具-獲取HTTP接口服務的各個時間

          當我們訪問一個網站或者網站接口服務,想知道"時間都去哪里了",這時候我們借助工具來分析。

          可以將時間大致分為兩部分:一部分是從我們請求到網站服務端所經歷的耗時,另一部分是服務端自身處理該服務完畢后響應回來的時間,這些都是可以作為后面結果分析的判斷依據。


          下面將介紹兩個方案,僅供參考。

          開始計時


          第一種方案:


          使用系統curl命令模擬網站服務請求,得到各個時間段的時間。

          需要注意的是:請確保curl 是最新版本,否則一些參數選項無法使用。


          例子:

          $ curl -w "Result: \n dnslookup: %{time_namelookup} \n connect: %{time_connect} \n appconnect: %{time_appconnect} \n pretransfer: %{time_pretransfer} \n starttransfer: %{time_starttransfer} \n total: %{time_total} \n ----\n time_redirect: %{time_redirect} \n ----\n size: %{size_download}\n" "https://www.baidu.com"
          <!DOCTYPE html>
          <!--STATUS OK--><html> <head><meta http-equiv=content-type content=text/html;charset=utf-8><meta http-equiv=X-UA-Compatible content=IE=Edge><meta content=always name=referrer><link rel=stylesheet type=text/css href=https://ss1.bdstatic.com/5eN1bjq8AAUYm2zgoY3K/r/www/cache/bdorz/baidu.min.css><title>百度一下,你就知道</title></head> <body link=#0000cc> <div id=wrapper> <div id=head> <div class=head_wrapper> <div class=s_form> <div class=s_form_wrapper> <div id=lg> <img hidefocus=true src=//www.baidu.com/img/bd_logo1.png width=270 height=129> </div> <form id=form name=f action=//www.baidu.com/s class=fm> <input type=hidden name=bdorz_come value=1> <input type=hidden name=ie value=utf-8> <input type=hidden name=f value=8> <input type=hidden name=rsv_bp value=1> <input type=hidden name=rsv_idx value=1> <input type=hidden name=tn value=baidu><span class="bg s_ipt_wr"><input id=kw name=wd class=s_ipt value maxlength=255 autocomplete=off autofocus=autofocus></span><span class="bg s_btn_wr"><input type=submit id=su value=百度一下 class="bg s_btn" autofocus></span> </form> </div> </div> <div id=u1> <a href=http://news.baidu.com name=tj_trnews class=mnav>新聞</a> <a href=https://www.hao123.com name=tj_trhao123 class=mnav>hao123</a> <a href=http://map.baidu.com name=tj_trmap class=mnav>地圖</a> <a href=http://v.baidu.com name=tj_trvideo class=mnav>視頻</a> <a href=http://tieba.baidu.com name=tj_trtieba class=mnav>貼吧</a> <noscript> <a href=http://m.jungjaehyung.com/uploadfile/2024/1011/20241011104128743.gif?login&tpl=mn&u=http%3A%2F%2Fwww.baidu.com%2f%3fbdorz_come%3d1 name=tj_login class=lb>登錄</a> </noscript> <script>document.write('<a href="http://m.jungjaehyung.com/uploadfile/2024/1011/20241011104128743.gif?login&tpl=mn&u='+ encodeURIComponent(window.location.href+ (window.location.search==="" ? "?" : "&")+ "bdorz_come=1")+ '" name="tj_login" class="lb">登錄</a>');
                          </script> <a href=//www.baidu.com/more/ name=tj_briicon class=bri style="display: block;">更多產品</a> </div> </div> </div> <div id=ftCon> <div id=ftConw> <p id=lh> <a href=http://home.baidu.com>關于百度</a> <a href=http://ir.baidu.com>About Baidu</a> </p> <p id=cp>?2017 Baidu <a href=http://www.baidu.com/duty/>使用百度前必讀</a>  <a href=http://jianyi.baidu.com/ class=cp-feedback>意見反饋</a> 京ICP證030173號  <img src=//www.baidu.com/img/gs.gif> </p> </div> </div> </div> </body> </html>
          Result: 
           dnslookup: 0.005 
           connect: 0.009 
           appconnect: 0.128 
           pretransfer: 0.128 
           starttransfer: 0.134 
           total: 0.134 
           ----
           time_redirect: 0.000 
           ----
           size: 2443


          參數:

          • time_namelookup:DNS解析時間,從請求開始到DNS解析完畢所用時間
          • time_connect:建立到服務器的 TCP 連接所用的時間
          • time_appconnect:從起始到應用側(SSL)連接/握手完成的耗時。(在7.19.0 版加入)
          • time_pretransfer:從開始至準備開始傳輸數據的時間
          • time_starttransfer:在發出請求之后,Web 服務器返回數據的第一個字節所用的時間
          • time_total:全部操作耗費的時間,單位為秒。精確到毫秒。
          • size_download:下載的總字節數。
          • speed_download:下載速度,單位-字節每秒。

          從上面的例子可以看到

          1. DNS解析耗時:0.005秒
          2. TCP建立連接的耗時:(0.009-0.005)=0.004秒
          3. SSL握手完成耗時:(0.128-0.009)=0.119秒
          4. server處理數據的時間:(0.134-0.128)=0.006秒
          5. 總體的耗時:0.134秒
          6. 整個過程沒有redirect,所以redirect的耗時為0


          上面還有個小技巧:


          $ cat ~/.curlrc 
          -w "Result: \n dnslookup: %{time_namelookup} \n connect: %{time_connect} \n appconnect: %{time_appconnect} \n pretransfer: %{time_pretransfer} \n starttransfer: %{time_starttransfer} \n total: %{time_total} \n ----\n time_redirect: %{time_redirect} \n ----\n size: %{size_download}\n"
          
          
          $ curl "https://www.baidu.com"


          我們把-w參數的值寫到curl配置文件~/.curlrc,這樣我們按照之前的curl命令訪問具體網址就可以得到各個時間。


          第二種方案:


          當你擁有Python的環境時,可以借助一個庫,可以方便清晰的了解耗時,這個庫就是httpstat。


          注意:該工具還是依賴底層curl命令,所以確保curl是最新版本。


          這里我以Python3環境為例,介紹下如何使用。


          • 安裝庫
          $ pip3 install httpstat


          • 檢查httpstat命令是否存在
          $ which httpstat
          ~/3rd/Python-3.7.4/bin/httpstat


          • 訪問網站
          $ httpstat "https://www.baidu.com"
          Connected to 163.177.151.110:443 from 10.10.10.10:41350
          
          HTTP/1.1 200 OK
          Accept-Ranges: bytes
          Cache-Control: private, no-cache, no-store, proxy-revalidate, no-transform
          Connection: keep-alive
          Content-Length: 2443
          Content-Type: text/html
          Date: Mon, 25 May 2020 03:14:53 GMT
          Etag: "58860402-98b"
          Last-Modified: Mon, 23 Jan 2017 13:24:18 GMT
          Pragma: no-cache
          Server: bfe/1.0.8.18
          Set-Cookie: BDORZ=27315; max-age=86400; domain=.baidu.com; path=/
          
          Body stored in: /tmp/tmp35tdqpkp
          
            DNS Lookup   TCP Connection   TLS Handshake   Server Processing   Content Transfer
          [    41ms    |       5ms      |     45ms      |        6ms        |        1ms       ]
                       |                |               |                   |                  |
              namelookup:41ms           |               |                   |                  |
                                  connect:46ms          |                   |                  |
                                              pretransfer:91ms              |                  |
                                                                starttransfer:97ms             |
                                                                                           total:98ms   
          


          是不是很直觀? so easy。


          總結:


          • 如果你不想用python,那么第一種方案最直接高效。
          • 如果你想用python,那么第二種方案顯示效果最佳。


          今天你get 到了嗎?喜歡的話,關注收藏下。

          GINX主要設計作為反向代理服務器,但隨著NGINX的發展,它同樣能作為正向代理的選項之一。正向代理本身并不復雜,而如何代理加密的HTTPS流量是正向代理需要解決的主要問題。本文將介紹利用NGINX來正向代理HTTPS流量兩種方案,及其使用場景和主要問題。

          HTTP/HTTPS正向代理的分類

          簡單介紹下正向代理的分類作為理解下文的背景知識:

          按客戶端有無感知的分類

          • 普通代理:在客戶端需要在瀏覽器中或者系統環境變量手動設置代理的地址和端口。如squid,在客戶端指定squid服務器IP和端口3128。
          • 透明代理:客戶端不需要做任何代理設置,“代理”這個角色對于客戶端是透明的。如企業網絡鏈路中的Web Gateway設備。

          按代理是否解密HTTPS的分類

          • 隧道代理 :也就是透傳代理。代理服務器只是在TCP協議上透傳HTTPS流量,對于其代理的流量的具體內容不解密不感知。客戶端和其訪問的目的服務器做直接TLS/SSL交互。本文中討論的NGINX代理方式屬于這種模式。
          • 中間人(MITM, Man-in-the-Middle)代理:代理服務器解密HTTPS流量,對客戶端利用自簽名證書完成TLS/SSL握手,對目的服務器端完成正常TLS交互。在客戶端-代理-服務器的鏈路中建立兩段TLS/SSL會話。如Charles,簡單原理描述可以參考文章。

          https://www.jianshu.com/p/405f9d76f8c4

          • 注:這種情況客戶端在TLS握手階段實際上是拿到的代理服務器自己的自簽名證書,證書鏈的驗證默認不成功,需要在客戶端信任代理自簽證書的Root CA證書。所以過程中是客戶端有感的。如果要做成無感的透明代理,需要向客戶端推送自建的Root CA證書,在企業內部環境下是可實現的。

          為什么正向代理處理HTTPS流量需要特殊處理?

          作為反向代理時,代理服務器通常終結 (terminate) HTTPS加密流量,再轉發給后端實例。HTTPS流量的加解密和認證過程發生在客戶端和反向代理服務器之間。

          而作為正向代理在處理客戶端發過來的流量時,HTTP加密封裝在了TLS/SSL中,代理服務器無法看到客戶端請求URL中想要訪問的域名,如下圖。所以代理HTTPS流量,相比于HTTP,需要做一些特殊處理。

          NGINX的解決方案

          根據前文中的分類方式,NGINX解決HTTPS代理的方式都屬于透傳(隧道)模式,即不解密不感知上層流量。具體的方式有如下7層和4層的兩類解決方案。

          HTTP CONNECT隧道 (7層解決方案)

          歷史背景

          早在1998年,也就是TLS還沒有正式誕生的SSL時代,主導SSL協議的Netscape公司就提出了關于利用web代理來tunneling SSL流量的INTERNET-DRAFT。其核心思想就是利用HTTP CONNECT請求在客戶端和代理之間建立一個HTTP CONNECT Tunnel,在CONNECT請求中需要指定客戶端需要訪問的目的主機和端口。Draft中的原圖如下:

          整個過程可以參考HTTP權威指南中的圖:

          1. 客戶端給代理服務器發送HTTP CONNECT請求。
          2. 代理服務器利用HTTP CONNECT請求中的主機和端口與目的服務器建立TCP連接。
          3. 代理服務器給客戶端返回HTTP 200響應。
          4. 客戶端和代理服務器建立起HTTP CONNECT隧道,HTTPS流量到達代理服務器后,直接通過TCP透傳給遠端目的服務器。代理服務器的角色是透傳HTTPS流量,并不需要解密HTTPS。

          NGINX ngx_http_proxy_connect_module模塊

          NGINX作為反向代理服務器,官方一直沒有支持HTTP CONNECT方法。但是基于NGINX的模塊化、可擴展性好的特性,阿里的@chobits提供了ngx_http_proxy_connect_module模塊,來支持HTTP CONNECT方法,從而讓NGINX可以擴展為正向代理。

          環境搭建

          以CentOS 7的環境為例。

          1) 安裝

          對于新安裝的環境,參考正常的安裝步驟和安裝這個模塊的步驟(https://github.com/chobits/ngx_http_proxy_connect_module),把對應版本的patch打上之后,在configure的時候加上參數--add-module=/path/to/ngx_http_proxy_connect_module,示例如下:

          ./configure \
          --user=www \
          --group=www \
          --prefix=/usr/local/nginx \
          --with-http_ssl_module \
          --with-http_stub_status_module \
          --with-http_realip_module \
          --with-threads \
          --add-module=/root/src/ngx_http_proxy_connect_module
          

          對于已經安裝編譯安裝完的環境,需要加入以上模塊,步驟如下:

          # 停止NGINX服務
          # systemctl stop nginx
          # 備份原執行文件
          # cp /usr/local/nginx/sbin/nginx /usr/local/nginx/sbin/nginx.bak
          # 在源代碼路徑重新編譯
          # cd /usr/local/src/nginx-1.16.0
          ./configure \
          --user=www \
          --group=www \
          --prefix=/usr/local/nginx \
          --with-http_ssl_module \
          --with-http_stub_status_module \
          --with-http_realip_module \
          --with-threads \
          --add-module=/root/src/ngx_http_proxy_connect_module
          # make
          # 不要make install
          # 將新生成的可執行文件拷貝覆蓋原來的nginx執行文件
          # cp objs/nginx /usr/local/nginx/sbin/nginx
          # /usr/bin/nginx -V
          nginx version: nginx/1.16.0
          built by gcc 4.8.5 20150623 (Red Hat 4.8.5-36) (GCC)
          built with OpenSSL 1.0.2k-fips 26 Jan 2017
          TLS SNI support enabled
          configure arguments: --user=www --group=www --prefix=/usr/local/nginx --with-http_ssl_module --with-http_stub_status_module --with-http_realip_module --with-threads --add-module=/root/src/ngx_http_proxy_connect_module
          

          2) nginx.conf文件配置

          server {
           listen 443;
           
           # dns resolver used by forward proxying
           resolver 114.114.114.114;
           # forward proxy for CONNECT request
           proxy_connect;
           proxy_connect_allow 443;
           proxy_connect_connect_timeout 10s;
           proxy_connect_read_timeout 10s;
           proxy_connect_send_timeout 10s;
           # forward proxy for non-CONNECT request
           location / {
           proxy_pass http://$host;
           proxy_set_header Host $host;
           }
           }
          

          使用場景

          7層需要通過HTTP CONNECT來建立隧道,屬于客戶端有感知的普通代理方式,需要在客戶端手動配置HTTP(S)代理服務器IP和端口。在客戶端用curl 加-x參數訪問如下:

          # curl https://www.baidu.com -svo /dev/null -x 39.105.196.164:443
          * About to connect() to proxy 39.105.196.164 port 443 (#0)
          * Trying 39.105.196.164...
          * Connected to 39.105.196.164 (39.105.196.164) port 443 (#0)
          * Establish HTTP proxy tunnel to www.baidu.com:443
          > CONNECT www.baidu.com:443 HTTP/1.1
          > Host: www.baidu.com:443
          > User-Agent: curl/7.29.0
          > Proxy-Connection: Keep-Alive
          >
          < HTTP/1.1 200 Connection Established
          < Proxy-agent: nginx
          <
          * Proxy replied OK to CONNECT request
          * Initializing NSS with certpath: sql:/etc/pki/nssdb
          * CAfile: /etc/pki/tls/certs/ca-bundle.crt
           CApath: none
          * SSL connection using TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
          * Server certificate:
          * subject: CN=baidu.com,O="Beijing Baidu Netcom Science Technology Co., Ltd",OU=service operation department,L=beijing,ST=beijing,C=CN
          ...
          > GET / HTTP/1.1
          > User-Agent: curl/7.29.0
          > Host: www.baidu.com
          > Accept: */*
          >
          < HTTP/1.1 200 OK
          ...
          { [data not shown]
          

          從上面-v參數打印出的細節,可以看到客戶端先往代理服務器39.105.196.164建立了HTTP CONNECT隧道,代理回復HTTP/1.1 200 Connection Established后就開始交互TLS/SSL握手和流量了。

          NGINX stream (4層解決方案)

          既然是使用透傳上層流量的方法,那可不可做成“4層代理”,對TCP/UDP以上的協議實現徹底的透傳呢?答案是可以的。NGINX官方從1.9.0版本開始支持ngx_stream_core_module模塊,模塊默認不build,需要configure時加上--with-stream選項來開啟。

          問題

          用NGINX stream在TCP層面上代理HTTPS流量肯定會遇到本文一開始提到的那個問題:代理服務器無法獲取客戶端想要訪問的目的域名。因為在TCP的層面獲取的信息僅限于IP和端口層面,沒有任何機會拿到域名信息。要拿到目的域名,必須要有拆上層報文獲取域名信息的能力,所以NGINX stream的方式不是完全嚴格意義上的4層代理,還是要略微借助些上層能力。

          ngx_stream_ssl_preread_module模塊

          要在不解密的情況下拿到HTTPS流量訪問的域名,只有利用TLS/SSL握手的第一個Client Hello報文中的擴展地址SNI (Server Name Indication)來獲取。NGINX官方從1.11.5版本開始支持利用ngx_stream_ssl_preread_module模塊來獲得這個能力,模塊主要用于獲取Client Hello報文中的SNI和ALPN信息。對于4層正向代理來說,從Client Hello報文中提取SNI的能力是至關重要的,否則NGINX stream的解決方案無法成立。同時這也帶來了一個限制,要求所有客戶端都需要在TLS/SSL握手中帶上SNI字段,否則NGINX stream代理完全沒辦法知道客戶端需要訪問的目的域名。

          環境搭建

          1) 安裝

          對于新安裝的環境,參考正常的安裝步驟,直接在configure的時候加上--with-stream,--with-stream_ssl_preread_module和--with-stream_ssl_module選項即可。示例如下:

          ./configure \
          --user=www \
          --group=www \
          --prefix=/usr/local/nginx \
          --with-http_ssl_module \
          --with-http_stub_status_module \
          --with-http_realip_module \
          --with-threads \
          --with-stream \
          --with-stream_ssl_preread_module \
          --with-stream_ssl_module
          

          對于已經安裝編譯安裝完的環境,需要加入以上3個與stream相關的模塊,步驟如下:

          # 停止NGINX服務
          # systemctl stop nginx
          # 備份原執行文件
          # cp /usr/local/nginx/sbin/nginx /usr/local/nginx/sbin/nginx.bak
          # 在源代碼路徑重新編譯
          # cd /usr/local/src/nginx-1.16.0
          # ./configure \
          --user=www \
          --group=www \
          --prefix=/usr/local/nginx \
          --with-http_ssl_module \
          --with-http_stub_status_module \
          --with-http_realip_module \
          --with-threads \
          --with-stream \
          --with-stream_ssl_preread_module \
          --with-stream_ssl_module
          # make
          # 不要make install
          # 將新生成的可執行文件拷貝覆蓋原來的nginx執行文件
          # cp objs/nginx /usr/local/nginx/sbin/nginx
          # nginx -V
          nginx version: nginx/1.16.0
          built by gcc 4.8.5 20150623 (Red Hat 4.8.5-36) (GCC)
          built with OpenSSL 1.0.2k-fips 26 Jan 2017
          TLS SNI support enabled
          configure arguments: --user=www --group=www --prefix=/usr/local/nginx --with-http_ssl_module --with-http_stub_status_module --with-http_realip_module --with-threads --with-stream --with-stream_ssl_preread_module --with-stream_ssl_module
          

          2) nginx.conf文件配置

          NGINX stream與HTTP不同,需要在stream塊中進行配置,但是指令參數與HTTP塊都是類似的,主要配置部分如下:

          stream {
           resolver 114.114.114.114;
           server {
           listen 443;
           ssl_preread on;
           proxy_connect_timeout 5s;
           proxy_pass $ssl_preread_server_name:$server_port;
           }
          }
          

          使用場景

          對于4層正向代理,NGINX對上層流量基本上是透傳,也不需要HTTP CONNECT來建立隧道。適合于透明代理的模式,比如將訪問的域名利用DNS解定向到代理服務器。我們可以通過在客戶端綁定/etc/hosts來模擬。

          在客戶端:

          cat /etc/hosts
          ...
          # 把域名www.baidu.com綁定到正向代理服務器39.105.196.164
          39.105.196.164 www.baidu.com
          # 正常利用curl來訪問www.baidu.com即可。
          # curl https://www.baidu.com -svo /dev/null
          * About to connect() to www.baidu.com port 443 (#0)
          * Trying 39.105.196.164...
          * Connected to www.baidu.com (39.105.196.164) port 443 (#0)
          * Initializing NSS with certpath: sql:/etc/pki/nssdb
          * CAfile: /etc/pki/tls/certs/ca-bundle.crt
           CApath: none
          * SSL connection using TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
          * Server certificate:
          * subject: CN=baidu.com,O="Beijing Baidu Netcom Science Technology Co., Ltd",OU=service operation department,L=beijing,ST=beijing,C=CN
          * start date: 5月 09 01:22:02 2019 GMT
          * expire date: 6月 25 05:31:02 2020 GMT
          * common name: baidu.com
          * issuer: CN=GlobalSign Organization Validation CA - SHA256 - G2,O=GlobalSign nv-sa,C=BE
          > GET / HTTP/1.1
          > User-Agent: curl/7.29.0
          > Host: www.baidu.com
          > Accept: */*
          >
          < HTTP/1.1 200 OK
          < Accept-Ranges: bytes
          < Cache-Control: private, no-cache, no-store, proxy-revalidate, no-transform
          < Connection: Keep-Alive
          < Content-Length: 2443
          < Content-Type: text/html
          < Date: Fri, 21 Jun 2019 05:46:07 GMT
          < Etag: "5886041d-98b"
          < Last-Modified: Mon, 23 Jan 2017 13:24:45 GMT
          < Pragma: no-cache
          < Server: bfe/1.0.8.18
          < Set-Cookie: BDORZ=27315; max-age=86400; domain=.baidu.com; path=/
          <
          { [data not shown]
          * Connection #0 to host www.baidu.com left intact
          

          常見問題

          1) 客戶端手動設置代理導致訪問不成功

          4層正向代理是透傳上層HTTPS流量,不需要HTTP CONNECT來建立隧道,也就是說不需要客戶端設置HTTP(S)代理。如果我們在客戶端手動設置HTTP(s)代理是否能訪問成功呢? 我們可以用curl -x來設置代理為這個正向服務器訪問測試,看看結果:

          # curl https://www.baidu.com -svo /dev/null -x 39.105.196.164:443
          * About to connect() to proxy 39.105.196.164 port 443 (#0)
          * Trying 39.105.196.164...
          * Connected to 39.105.196.164 (39.105.196.164) port 443 (#0)
          * Establish HTTP proxy tunnel to www.baidu.com:443
          > CONNECT www.baidu.com:443 HTTP/1.1
          > Host: www.baidu.com:443
          > User-Agent: curl/7.29.0
          > Proxy-Connection: Keep-Alive
          >
          * Proxy CONNECT aborted
          * Connection #0 to host 39.105.196.164 left intact
          

          可以看到客戶端試圖于正向NGINX前建立HTTP CONNECT tunnel,但是由于NGINX是透傳,所以把CONNECT請求直接轉發給了目的服務器。目的服務器不接受CONNECT方法,所以最終出現"Proxy CONNECT aborted",導致訪問不成功。

          2) 客戶端沒有帶SNI導致訪問不成功

          上文提到用NGINX stream做正向代理的關鍵因素之一是利用ngx_stream_ssl_preread_module提取出Client Hello中的SNI字段。如果客戶端客戶端不攜帶SNI字段,會造成代理服務器無法獲知目的域名的情況,導致訪問不成功。

          在透明代理模式下(用手動綁定hosts的方式模擬),我們可以在客戶端用openssl來模擬:

          # openssl s_client -connect www.baidu.com:443 -msg
          CONNECTED(00000003)
          >>> TLS 1.2 [length 0005]
           16 03 01 01 1c
          >>> TLS 1.2 Handshake [length 011c], ClientHello
           01 00 01 18 03 03 6b 2e 75 86 52 6c d5 a5 80 d7
           a4 61 65 6d 72 53 33 fb 33 f0 43 a3 aa c2 4a e3
           47 84 9f 69 8b d6 00 00 ac c0 30 c0 2c c0 28 c0
           24 c0 14 c0 0a 00 a5 00 a3 00 a1 00 9f 00 6b 00
           6a 00 69 00 68 00 39 00 38 00 37 00 36 00 88 00
           87 00 86 00 85 c0 32 c0 2e c0 2a c0 26 c0 0f c0
           05 00 9d 00 3d 00 35 00 84 c0 2f c0 2b c0 27 c0
           23 c0 13 c0 09 00 a4 00 a2 00 a0 00 9e 00 67 00
           40 00 3f 00 3e 00 33 00 32 00 31 00 30 00 9a 00
           99 00 98 00 97 00 45 00 44 00 43 00 42 c0 31 c0
           2d c0 29 c0 25 c0 0e c0 04 00 9c 00 3c 00 2f 00
           96 00 41 c0 12 c0 08 00 16 00 13 00 10 00 0d c0
           0d c0 03 00 0a 00 07 c0 11 c0 07 c0 0c c0 02 00
           05 00 04 00 ff 01 00 00 43 00 0b 00 04 03 00 01
           02 00 0a 00 0a 00 08 00 17 00 19 00 18 00 16 00
           23 00 00 00 0d 00 20 00 1e 06 01 06 02 06 03 05
           01 05 02 05 03 04 01 04 02 04 03 03 01 03 02 03
           03 02 01 02 02 02 03 00 0f 00 01 01
          140285606590352:error:140790E5:SSL routines:ssl23_write:ssl handshake failure:s23_lib.c:177:
          ---
          no peer certificate available
          ---
          No client certificate CA names sent
          ---
          SSL handshake has read 0 bytes and written 289 bytes
          ...
          

          openssl s_client默認不帶SNI,可以看到上面的請求在TLS/SSL握手階段,發出Client Hello后就結束了。因為代理服務器不知道要把Client Hello往哪個目的域名轉發。

          如果用openssl帶servername參數來指定SNI,則可以正常訪問成功,命令如下:

          # openssl s_client -connect www.baidu.com:443 -servername www.baidu.com
          

          總結

          本文總結了NGINX利用HTTP CONNECT隧道和NGINX stream兩種方式做HTTPS正向代理的原理,環境搭建,使用場景和主要問題,希望給大家在做各種場景的正向代理時提供參考。

          作者:懷知

          者 | LightZhang666

          責編 | 屠敏

          出品 | CSDN 博客

          本篇文章包含了curl的常用案例使用。

          常見網頁訪問示例

          基本用法

          訪問一個網頁:

          curl https://www.baidu.com

          執行后,相關的網頁信息會打印出來。

          進度條展示

          有時候我們不需要進度表展示,而需要進度條展示。比如:下載文件時。

          可以通過 -#, --progress-bar 選項實現。

          [root@iZ28xbsfvc4Z 20190713]# curl https://www.baidu.com | head -n1 # 進度表顯示
          % Total % Received % Xferd Average Speed Time Time Time Current
          Dload Upload Total Spent Left Speed
          100 2443 100 2443 0 0 11662 0 --:--:-- --:--:-- --:--:-- 11688
          <!DOCTYPE html>
          [root@iZ28xbsfvc4Z 20190713]# curl -# https://www.baidu.com | head -n1 # 進度條顯示
          ######################################################################## 100.0%
          <!DOCTYPE html>

          靜默模式與錯誤信息打印

          當我們做一些操作時,可能會出現進度表。這時我們可以使用 -s, --silent 靜默模式去掉這些不必要的信息。

          如果使用 -s, --silent 時,還需要打印錯誤信息,那么還需要使用 -S, --show-error 選項。

          靜默模式示例

          [root@iZ28xbsfvc4Z ~]# curl https://www.baidu.com | head -n1
          % Total % Received % Xferd Average Speed Time Time Time Current
          Dload Upload Total Spent Left Speed
          100 2443 100 2443 0 0 11874 0 --:--:-- --:--:-- --:--:-- 11859
          <!DOCTYPE html>
          [root@iZ28xbsfvc4Z ~]# curl -s https://www.baidu.com | head -n1
          <!DOCTYPE html>

          靜默模式結合錯誤信息打印

          [root@iZ28xbsfvc4Z 20190713]# curl -s https://140.205.16.113/ 
          [root@iZ28xbsfvc4Z 20190713]#
          [root@iZ28xbsfvc4Z 20190713]# curl -sS https://140.205.16.113/
          curl: (51) Unable to communicate securely with peer: requested domain name does not match the server's certificate.

          顯示詳細操作信息

          使用 -v, --verbose 選項實現。

          以 > 開頭的行表示curl發送的"header data";< 表示curl接收到的通常情況下隱藏的"header data";而以 * 開頭的行表示curl提供的附加信息。

          [root@iZ28xbsfvc4Z 20190712]# curl -v https://www.baidu.com
          * About to connect to www.baidu.com port 443 (#0)
          * Trying 180.101.49.12...
          * Connected to www.baidu.com (180.101.49.12) port 443 (#0)
          * Initializing NSS with certpath: sql:/etc/pki/nssdb
          * CAfile: /etc/pki/tls/certs/ca-bundle.crt
          CApath: none
          * SSL connection using TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
          * Server certificate:
          * subject: CN=baidu.com,O="Beijing Baidu Netcom Science Technology Co., Ltd",OU=service operation department,L=beijing,ST=beijing,C=CN
          * start date: May 09 01:22:02 2019 GMT
          * expire date: Jun 25 05:31:02 2020 GMT
          * common name: baidu.com
          * issuer: CN=GlobalSign Organization Validation CA - SHA256 - G2,O=GlobalSign nv-sa,C=BE
          > GET / HTTP/1.1
          > User-Agent: curl/7.29.0
          > Host: www.baidu.com
          > Accept: */*
          >
          < HTTP/1.1 200 OK
          < Accept-Ranges: bytes
          < Cache-Control: private, no-cache, no-store, proxy-revalidate, no-transform
          < Connection: Keep-Alive
          < Content-Length: 2443
          < Content-Type: text/html
          < Date: Fri, 12 Jul 2019 08:26:23 GMT
          < Etag: "588603eb-98b"
          < Last-Modified: Mon, 23 Jan 2017 13:23:55 GMT
          < Pragma: no-cache
          < Server: bfe/1.0.8.18
          < Set-Cookie: BDORZ=27315; max-age=86400; domain=.baidu.com; path=/
          <
          <!DOCTYPE html>
          ……………… # curl 網頁的具體信息

          指定訪問的請求方法

          當然curl默認使用GET方式訪問。使用了 -d, --data <data> 選項,那么會默認為 POST方法訪問。如果此時還想實現 GET 訪問,那么可以使用 -G, --get 選項強制curl 使用GET方法訪問。

          同時 -X, --request <command> 選項也可以指定訪問方法。

          POST請求和數據傳輸

          為了抓包查看信息所以使用了 --local-port <num>[-num] 選項,在實際應用中不需要該選項。

          [root@iZ28xbsfvc4Z ~]# curl -sv --local-port 9000 -X POST -d 'user=zhang&pwd=123456' http://www.zhangblog.com/2019/06/24/domainexpire/ | head -n1 
          ## 或者
          [root@iZ28xbsfvc4Z ~]# curl -sv --local-port 9000 -d 'user=zhang&pwd=123456' http://www.zhangblog.com/2019/06/24/domainexpire/ | head -n1
          * About to connect to www.zhangblog.com port 80 (#0)
          * Trying 120.27.48.179...
          * Connected to www.zhangblog.com (120.27.48.179) port 80 (#0)
          > POST /2019/06/24/domainexpire/ HTTP/1.1 # POST 請求方法
          > User-Agent: curl/7.29.0
          > Host: www.zhangblog.com
          > Accept: */*
          > Content-Length: 21
          > Content-Type: application/x-www-form-urlencoded
          >
          } [data not shown]
          * upload completely sent off: 21 out of 21 bytes
          < HTTP/1.1 405 Not Allowed
          < Server: nginx/1.14.2
          < Date: Thu, 18 Jul 2019 07:56:23 GMT
          < Content-Type: text/html
          < Content-Length: 173
          < Connection: keep-alive
          <
          { [data not shown]
          * Connection #0 to host www.zhangblog.com left intact
          <html>

          抓包信息

          [root@iZ28xbsfvc4Z tcpdump]# tcpdump -i any port 9000 -A -s 0

          指定請求方法

          curl -vs -X POST https://www.baidu.com | head -n1
          curl -vs -X PUT https://www.baidu.com | head -n1

          保存訪問網頁

          使用linux的重定向功能保存

          curl www.baidu.com >> baidu.html

          使用curl的大O選項

          通過 -O, --remote-name 選項實現。

          [root@iZ28xbsfvc4Z 20190712]# curl -O https://www.baidu.com # 使用了 -O 選項,必須指定到具體的文件 錯誤使用
          curl: Remote file name has no length!
          curl: try 'curl --help' or 'curl --manual' for more information
          [root@iZ28xbsfvc4Z 20190712]# curl -O https://www.baidu.com/index.html # 使用了 -O 選項,必須指定到具體的文件 正確使用
          % Total % Received % Xferd Average Speed Time Time Time Current
          Dload Upload Total Spent Left Speed
          100 2443 100 2443 0 0 13289 0 --:--:-- --:--:-- --:--:-- 13349

          使用curl的小o選項

          通過 -o, --output <file> 選項實現。

          [root@iZ28xbsfvc4Z 20190713]# curl -o sina.txt https://www.sina.com.cn/ # 單個操作
          [root@iZ28xbsfvc4Z 20190713]# ll
          -rw-r--r-- 1 root root 154 Jul 13 21:06 sina.txt
          [root@iZ28xbsfvc4Z 20190703]# curl "http://www.{baidu,douban}.com" -o "site_#1.txt" # 批量操作,注意curl 的地址需要用引號括起來
          [1/2]: http://www.baidu.com --> site_baidu.txt
          % Total % Received % Xferd Average Speed Time Time Time Current
          Dload Upload Total Spent Left Speed
          100 2381 100 2381 0 0 46045 0 --:--:-- --:--:-- --:--:-- 46686

          [2/2]: http://www.douban.com --> site_douban.txt
          100 162 100 162 0 0 3173 0 --:--:-- --:--:-- --:--:-- 3173
          [root@iZ28xbsfvc4Z 20190703]#
          [root@iZ28xbsfvc4Z 20190703]# ll
          total 220
          -rw-r--r-- 1 root root 2381 Jul 4 16:53 site_baidu.txt
          -rw-r--r-- 1 root root 162 Jul 4 16:53 site_douban.txt

          允許不安全訪問

          當我們使用curl進行https訪問訪問時,如果SSL證書是我們自簽發的證書,那么這個時候需要使用 -k, --insecure 選項,允許不安全的訪問。

          [root@iZ28xbsfvc4Z ~]# curl https://140.205.16.113/ # 被拒絕
          curl: (51) Unable to communicate securely with peer: requested domain name does not match the server's certificate.
          [root@iZ28xbsfvc4Z ~]#
          [root@iZ28xbsfvc4Z ~]# curl -k https://140.205.16.113/ # 允許執行不安全的證書連接
          <!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
          <html>
          <head><title>403 Forbidden</title></head>
          <body bgcolor="white">
          <h1>403 Forbidden</h1>
          <p>You don't have permission to access the URL on this server.<hr/>Powered by Tengine</body>
          </html>

          獲取HTTP響應狀態碼

          在腳本中,這是很常見的測試網站是否正常的用法。

          通過 -w, --write-out <format> 選項實現。

          [root@iZ28xbsfvc4Z 20190713]# curl -o /dev/ -s -w %{http_code} https://baidu.com
          302[root@iZ28xbsfvc4Z 20190713]#
          [root@iZ28xbsfvc4Z 20190713]#
          [root@iZ28xbsfvc4Z 20190713]# curl -o /dev/ -s -w %{http_code} https://www.baidu.com
          200[root@iZ28xbsfvc4Z 20190713]#

          指定proxy服務器以及其端口

          很多時候上網需要用到代理服務器(比如是使用代理服務器上網或者因為使用curl別人網站而被別人屏蔽IP地址的時候),幸運的是curl通過使用 -x, --proxy <[protocol://][user:password@]proxyhost[:port]> 選項來支持設置代理。

          curl -x 192.168.100.100:1080 https://www.baidu.com

          模仿瀏覽器訪問

          有些網站需要使用特定的瀏覽器去訪問他們,有些還需要使用某些特定的瀏覽器版本。我們可以通過 -A, --user-agent <agent string> 或者 -H, --header <header> 選項實現模擬瀏覽器訪問。

          curl -A "Mozilla/5.0 (Windows NT 10.0; Win64; x64) Chrome/75.0.3770.999" http://www.zhangblog.com/2019/06/24/domainexpire/ 
          或者
          curl -H 'User-Agent: Mozilla/5.0' http://www.zhangblog.com/2019/06/24/domainexpire/

          偽造referer(盜鏈)

          有些網站的網頁對http訪問的鏈接來源做了訪問限制,這些限制幾乎都是通過referer來實現的。

          比如:要求是先訪問首頁,然后再訪問首頁中的郵箱頁面,這時訪問郵箱的referer地址就是訪問首頁成功后的頁面地址。如果服務器發現對郵箱頁面訪問的referer地址不是首頁的地址,就斷定那是個盜連了。

          可以通過 -e, --referer 或則 -H, --header <header> 實現偽造 referer 。

          curl -e 'https://www.baidu.com' http://www.zhangblog.com/2019/06/24/domainexpire/
          或者
          curl -H 'Referer: https://www.baidu.com' http://www.zhangblog.com/2019/06/24/domainexpire/

          構造HTTP請求頭

          可以通過 -H, --header <header> 實現構造http請求頭。

          curl -H 'Connection: keep-alive' -H 'Referer: https://sina.com.cn' -H 'User-Agent: Mozilla/1.0' http://www.zhangblog.com/2019/06/24/domainexpire/

          保存響應頭信息

          可以通過 -D, --dump-header <file> 選項實現。

          [root@iZ28xbsfvc4Z 20190703]# curl -D baidu_header.info www.baidu.com 
          ………………
          [root@iZ28xbsfvc4Z 20190703]# ll
          total 4
          -rw-r--r-- 1 root root 400 Jul 3 10:11 baidu_header.info # 生成的頭文件

          限時訪問

          --connect-timeout <seconds> 連接服務端的超時時間。這只限制了連接階段,一旦curl連接了此選項就不再使用了。

          # 當前 https://www.zhangXX.com 是國外服務器,訪問受限
          [root@iZ28xbsfvc4Z ~]# curl --connect-timeout 10 https://www.zhangXX.com | head
          % Total % Received % Xferd Average Speed Time Time Time Current
          Dload Upload Total Spent Left Speed
          0 0 0 0 0 0 0 0 --:--:-- 0:00:10 --:--:-- 0
          curl: (28) Connection timed out after 10001 milliseconds

          -m, --max-time <seconds> 允許整個操作花費的最大時間(以秒為單位)。這對于防止由于網絡或鏈接變慢而導致批處理作業掛起數小時非常有用。

          [root@iZ28xbsfvc4Z ~]# curl -m 10 --limit-rate 5 http://www.baidu.com/ | head # 超過10秒后,斷開連接
          % Total % Received % Xferd Average Speed Time Time Time Current
          Dload Upload Total Spent Left Speed
          2 2381 2 50 0 0 4 0 0:09:55 0:00:10 0:09:45 4
          curl: (28) Operation timed out after 10103 milliseconds with 50 out of 2381 bytes received
          <!DOCTYPE html>
          <!--STATUS OK--><html> <head><met
          ### 或
          [root@iZ28xbsfvc4Z ~]# curl -m 10 https://www.zhangXX.com | head # 超過10秒后,斷開連接
          % Total % Received % Xferd Average Speed Time Time Time Current
          Dload Upload Total Spent Left Speed
          0 0 0 0 0 0 0 0 --:--:-- 0:00:10 --:--:-- 0
          curl: (28) Connection timed out after 10001 milliseconds

          顯示抓取錯誤

          當我們請求訪問失敗時或者沒有該網頁時,網站一般都會給出一個錯誤的提示頁面。

          如果我們不需要這個錯誤頁面,只想得到簡潔的錯誤信息。那么可以通過 -f, --fail 選項實現。

          [root@iZ28xbsfvc4Z 20190713]# curl http://www.zhangblog.com/201912312
          <html>
          <head><title>404 Not Found</title></head>
          <body bgcolor="white">
          <center><h1>404 Not Found</h1></center>
          <hr><center>nginx/1.14.2</center>
          </body>
          </html>
          [root@iZ28xbsfvc4Z 20190713]# curl -f http://www.zhangblog.com/201912312 # 得到更簡潔的錯誤信息
          curl: (22) The requested URL returned error: 404 Not Found

          表單登錄與cookie使用

          參見「Linux curl 表單登錄或提交與cookie使用」:http://www.zhangblog.com/2019/07/20/curl03/

          文件上傳與下載

          涉及 FTP 服務,簡單快速搭建可參考:《CentOS7下安裝FTP服務》「https://www.cnblogs.com/zhi-leaf/p/5983550.html」

          文件下載網頁文件下載

          # 以進度條展示,而不是進度表展示
          [root@iZ28xbsfvc4Z 20190715]# curl -# -o tmp.data2 http://www.zhangblog.com/uploads/tmp/tmp.data
          ######################################################################## 100.0%

          FTP文件下載

          說明1:其中 ftp1 用戶是ftp服務端的賬號,具體家目錄是:/mnt/ftp1

          說明2:當我們使用 curl 通過 FTP 進行下載時,后面跟的路徑都是:當前使用的 ftp 賬號家目錄為基礎的相對路徑,然后找到的目標文件。

          示例1

          # 其中 tmp.data 的絕對路徑是:/mnt/ftp1/tmpdata/tmp.data ;ftp1 賬號的家目錄是:/mnt/ftp1
          # 說明:/tmpdata/tmp.data 這個路徑是針對 ftp1 賬號的家目錄而言的
          [yun@nginx_proxy01 20190715]$ curl -O ftp://ftp1:123456@172.16.1.195:21/tmpdata/tmp.data
          # 或者
          [yun@nginx_proxy01 20190715]$ curl -O -u ftp1:123456 ftp://172.16.1.195:21/tmpdata/tmp.data
          % Total % Received % Xferd Average Speed Time Time Time Current
          Dload Upload Total Spent Left Speed
          100 2048M 100 2048M 0 0 39.5M 0 0:00:51 0:00:51 --:--:-- 143M

          示例2

          # 其中 nginx-1.14.2.tar.gz 的絕對路徑是:/tmp/nginx-1.14.2.tar.gz ;ftp1 賬號的家目錄是:/mnt/ftp1
          # 說明:/../../tmp/nginx-1.14.2.tar.gz 這個路徑是針對 ftp1 賬號的家目錄而言的
          [yun@nginx_proxy01 20190715]$ curl -O ftp://ftp1:123456@172.16.1.195:21/../../tmp/nginx-1.14.2.tar.gz
          # 或者
          [yun@nginx_proxy01 20190715]$ curl -O -u ftp1:123456 ftp://172.16.1.195:21/../../tmp/nginx-1.14.2.tar.gz
          % Total % Received % Xferd Average Speed Time Time Time Current
          Dload Upload Total Spent Left Speed
          100 991k 100 991k 0 0 5910k 0 --:--:-- --:--:-- --:--:-- 5937k

          文件上傳

          FTP文件上傳

          可以通過 -T, --upload-file <file> 選項實現。

          說明1:其中 ftp1 用戶是ftp服務端的賬號,具體家目錄是:/mnt/ftp1

          # 其中 tmp_client.data 是客戶端本地文件; 
          # /tmpdata/ 這個路徑是針對 ftp1 賬號的家目錄而言的,且上傳時該目錄必須是存在的,否則上傳失敗。
          # 因此上傳后文件在ftp服務端的絕對路徑是:/mnt/ftp1/tmpdata/tmp_client.data
          [yun@nginx_proxy01 20190715]$ curl -T tmp_client.data ftp://ftp1:123456@172.16.1.195:21/tmpdata/
          # 或者
          [yun@nginx_proxy01 20190715]$ curl -T tmp_client.data -u ftp1:123456 ftp://172.16.1.195:21/tmpdata/
          % Total % Received % Xferd Average Speed Time Time Time Current
          Dload Upload Total Spent Left Speed
          100 2048M 0 0 100 2048M 0 95.4M 0:00:21 0:00:21 --:--:-- 49.3M

          斷點續傳

          使用 -C, --continue-at <offset> 選項實現。其中使用 “-C -”「注意有空格和無空格的情況」,告訴curl自動找出在哪里/如何恢復傳輸。

          網頁端斷點續傳下載

          curl -C - -o tmp.data http://www.zhangblog.com/uploads/tmp/tmp.data # 下載一個 2G 的文件

          FTP斷點續傳下載

          細節就不多說了,可參見上面的「FTP文件下載

          curl -C - -o tmp.data1 ftp://ftp1:123456@172.16.1.195:21/tmpdata/tmp.data # 下載一個 2G 的文件
          # 或則
          curl -C - -o tmp.data1 -u ftp1:123456 ftp://172.16.1.195:21/tmpdata/tmp.data # 下載一個 2G 的文件

          分段下載

          有時文件比較大,或者難以迅速傳輸,而利用分段傳輸,可以實現穩定、高效并且有保障的傳輸,更具有實用性,同時容易對差錯文件進行更正。

          可使用 -r, --range <range> 選項實現。

          如下示例使用了同一張圖片,大小為 18196 字節。

          網頁端分段下載分段下載

          [root@iZ28xbsfvc4Z 20190715]# curl -I http://www.zhangblog.com/uploads/hexo/00.jpg # 查看文件大小
          HTTP/1.1 200 OK
          Server: nginx/1.14.2
          Date: Mon, 15 Jul 2019 03:23:44 GMT
          Content-Type: image/jpeg
          Content-Length: 18196 # 文件大小
          Last-Modified: Fri, 05 Jul 2019 08:04:58 GMT
          Connection: keep-alive
          ETag: "5d1f04aa-4714"
          Accept-Ranges: bytes
          ### 分段下載一個文件
          [root@iZ28xbsfvc4Z 20190715]# curl -r 0-499 -o 00-jpg.part1 http://www.zhangblog.com/uploads/hexo/00.jpg
          [root@iZ28xbsfvc4Z 20190715]# curl -r 500-999 -o 00-jpg.part2 http://www.zhangblog.com/uploads/hexo/00.jpg
          [root@iZ28xbsfvc4Z 20190715]# curl -r 1000- -o 00-jpg.part3 http://www.zhangblog.com/uploads/hexo/00.jpg

          查看下載文件

          [root@iZ28xbsfvc4Z 20190715]# ll
          total 36
          -rw-r--r-- 1 root root 500 Jul 15 11:25 00-jpg.part1
          -rw-r--r-- 1 root root 500 Jul 15 11:25 00-jpg.part2
          -rw-r--r-- 1 root root 17196 Jul 15 11:26 00-jpg.part3

          文件合并

          [root@iZ28xbsfvc4Z 20190715]# cat 00-jpg.part1 00-jpg.part2 00-jpg.part3 > 00.jpg
          [root@iZ28xbsfvc4Z 20190715]# ll 00.jpg
          total 56
          -rw-r--r-- 1 root root 18196 Jul 15 11:29 00.jpg

          FTP分段下載分段下載

          [yun@nginx_proxy01 20190715]$ curl -r 0-499 -o 00-jpg.part1 ftp://ftp1:123456@172.16.1.195:21/tmpdata/00.jpg
          [yun@nginx_proxy01 20190715]$ curl -r 500-999 -o 00-jpg.part2 ftp://ftp1:123456@172.16.1.195:21/tmpdata/00.jpg
          [yun@nginx_proxy01 20190715]$ curl -r 1000- -o 00-jpg.part3 ftp://ftp1:123456@172.16.1.195:21/tmpdata/00.jpg

          查看下載文件

          [yun@nginx_proxy01 20190715]$ ll 00-jpg.part*
          -rw-rw-r-- 1 yun yun 500 Jul 15 17:59 00-jpg.part1
          -rw-rw-r-- 1 yun yun 500 Jul 15 18:00 00-jpg.part2
          -rw-rw-r-- 1 yun yun 17196 Jul 15 18:00 00-jpg.part3

          文件合并

          [yun@nginx_proxy01 20190715]$ cat 00-jpg.part1 00-jpg.part2 00-jpg.part3 > 00.jpg
          [yun@nginx_proxy01 20190715]$ ll 00.jpg
          -rw-rw-r-- 1 yun yun 18196 Jul 15 18:02 00.jpg

          聲明:本文為CSDN博主「LightZhang666」的原創文章,版權歸作者所有,如需轉載請聯系作者。

          原文:https://blog.csdn.net/woshizhangliang999/article/details/98946071

          【End】


          主站蜘蛛池模板: 伊人色综合网一区二区三区| 亚洲国产高清在线精品一区| 亚洲日本一区二区三区在线| 3D动漫精品啪啪一区二区下载| 丝袜人妻一区二区三区网站| 国产亚洲综合一区二区三区 | AV怡红院一区二区三区| 无码囯产精品一区二区免费| 伦理一区二区三区| 无码毛片一区二区三区视频免费播放| 日韩一区二区a片免费观看| 精品性影院一区二区三区内射| 亚洲色精品aⅴ一区区三区| 中文字幕一区在线观看| 97精品国产福利一区二区三区| 一区二区三区在线播放| 欧洲精品一区二区三区在线观看| 国产伦理一区二区三区| 在线观看国产一区二区三区 | 亚洲av无码一区二区三区网站| 中文字幕精品无码一区二区三区 | 国产精品一区二区无线| 成人区人妻精品一区二区三区| 无码一区二区波多野结衣播放搜索| 99久久无码一区人妻a黑| 国产精品高清一区二区人妖| 国产高清在线精品一区| 亚洲av成人一区二区三区在线播放| 亚洲乱色熟女一区二区三区蜜臀 | 日本一区二三区好的精华液| 男插女高潮一区二区| 在线观看国产一区二区三区| 亚洲AV无码一区二区三区在线观看 | 精品国产毛片一区二区无码| 手机看片一区二区| 免费无码毛片一区二区APP| 日韩免费一区二区三区在线播放 | 无码人妻精品一区二区三区久久| 3d动漫精品一区视频在线观看| 欧美激情国产精品视频一区二区| 亚洲精品日韩一区二区小说|