Masahiko Kitamura

curlを用いたコマンドラインでのアカマイデバッグ方法

Blog Post created by Masahiko Kitamura Employee on Jan 11, 2018

今回はmacOSやLinuxに標準インストールされ,コマンドライン上で利用できるHTTPクライアント"curl"を用いてアカマイのデバッグをする方法について説明します.

 

アカマイのデバッグ方法に関しては,こちらの記事でスプーフィング(hostsファイル書き換え)とブラウザを用いた動作確認方法を解説しており,こちらの方が一般的かもしれません.しかし,curlを用いたデバッグ方法は通常のブラウザを用いる方法と比べると下記のようなメリットがあります.

 

  1. terminalから実行できる
  2. スプーフィング(hostsファイル書き換え)が不要
  3. プラグインなしでakamaiデバッグヘッダを確認できる
  4. 処理がバッチ化できテスト自動化が容易
  5. リモートマシン上でのテストが容易(ssh経由などで利用)

 

今回は下記のような環境を想定して,実際にcurlコマンドを用いてアカマイの動作確認をする方法を具体的にみていきたいと思います.

 

 

1. エッジサーバにリクエストを出す

スプーフィングをせずにcurlを用いてステージングテストするには下記のようにcurlコマンドを実行します.

$curl -I -X GET -k -H "Host: www.myexample.com" 'https://www.myexample.com.edgekey-staging.net/foo/bar/index.html'

HTTP/2 200 OK
Accept-Ranges: bytes
Cache-Control: max-age=1
Content-Length: 18477
Content-Type: text/html
Expires: Sat, 05 Aug 2017 00:30:20 GMT
Last-Modified: Tue, 01 Aug 2017 07:11:16 GMT
Server: Apache
Date: Sat, 05 Aug 2017 00:30:19 GMT
Connection: keep-alive
X-Akamai-Staging: ESSL

コマンドオプションの意味は下記の通りです.

  • -I: レスポンスヘッダのみを表示
  • -X GET: リクエストとしてGET Methodを指定
  • -k : SSL handshakeにおいて,SSL証明書のCommon Nameマッチエラーを無視
  • -H "Host: www.myexample.com": hostヘッダにプロパティホスト名を指定する

 

リクエストURIのホスト部分にステージングのエッジホスト名(www.myexample.com.edgekey-staging.net)を指定することで,ステージングエッジサーバへリクエストを送信することが可能になります.ただし,SSL handshakeにおいて,Common Nameミスマッチ(CN=www.myexample.com vs リクエスト=www.myexample.com.edgekey-staging.net)が発生するため,-kオプションでエラー回避を行う必要があります.

 

リクエストの結果をみると,X-Akamai-Staging: ESSL が返ってくるため,ステージングエッジサーバへアクセスができていることを確認できます.

 

上記のURIのホスト名をwww.myexample.com.edgekey.netとすることで,アカマイプロダクションのエッジサーバへリクエストを送信することができます.この方法は直接エッジホスト名を指定しているため,CNAME前であってもアカマイプロダクションのテストが可能です.

 

 

2. アカマイデバッグヘッダを確認する

こちらのブログ記事 Akamai設定の検証やデバッグ方法(Chrome編) にあるとおり,アカマイのエッジサーバはPragmaヘッダを含めてリクエストを出すとレスポンスにデバッグ情報を載せて返してくれます.curlにおいても

  • -H "Pragma: akamai-x-cache-on,akamai-x-cache-remote-on,akamai-x-check-cacheable,akamai-x-get-cache-key,akamai-x-get-extracted-values,akamai-x-get-request-id,akamai-x-serial-no, akamai-x-get-true-cache-key"

オプションを追加することで,アカマイデバッグヘッダを参照することが可能になります.

 

$ curl -I -k -X GET -H "host: www.myexample.com" 'https://www.myexample.com.edgekey-staging.net/foo/bar/index.html' -H "Pragma: akamai-x-cache-on,akamai-x-cache-remote-on,akamai-x-check-cacheable,akamai-x-get-cache-key,akamai-x-get-extracted-values,akamai-x-get-request-id,akamai-x-serial-no, akamai-x-get-true-cache-key"

HTTP/2 200
content-type: text/html
last-modified: Tue, 25 Apr 2017 08:22:18 GMT
accept-ranges: bytes
server: Apache
x-check-cacheable: NO
x-akamai-request-id: 332fc.1254a1
x-akamai-transformed: 9 3538 0 pmb=mRUM,1
date: Wed, 27 Dec 2017 06:22:25 GMT
content-length: 4567
x-cache: TCP_MISS from a23-48-169-52.deploy.akamaitechnologies.com (AkamaiGHost/9.1.4.4-21488373) (-)
x-cache-key: S/D/98765/123456/000/www.myexample.com/space/foo/bar/index.html
x-true-cache-key: /D/000/www.myexample.com/space/foo/bar/index.html
x-akamai-session-info: name=AKA_PM_BASEDIR; value=
x-akamai-session-info: name=AKA_PM_BYPASS_TD; value=true
x-serial: 98765
x-cache-remote: TCP_MISS from a23-48-168-37.deploy.akamaitechnologies.com (AkamaiGHost/9.1.4.4-21488373) (-)
x-akamai-staging: ESSL

上記の通り,デバッグ情報が参照できます.

 

 

3. SSL handshake + 送信ヘッダを確認する

問題切り分けのために,さらに詳細なリクエスト/レスポンスの過程を表示したい場合が往往にしてあります.curlでは-svオプションをつけることで,SSL handshake過程,リクエスト過程,レスポンス過程を参照することができます.

$ curl -I -X GET -k -H "Host: www.myexample.com" https://www.myexample.com.edgekey-staging.net/foo/bar/index.html -sv > /dev/null -H "Pragma: akamai-x-cache-on,akamai-x-cache-remote-on,akamai-x-check-cacheable,akamai-x-get-cache-key,akamai-x-get-extracted-values,akamai-x-get-request-id,akamai-x-serial-no, akamai-x-get-true-cache-key"

*   Trying 104.71.85.161...
* Connected to www.myexample.com.edgekey-staging.net (104.71.85.161) port 443 (#0)
* ALPN, offering h2
* ALPN, offering http/1.1
* Cipher selection: ALL:!EXPORT:!EXPORT40:!EXPORT56:!aNULL:!LOW:!RC4:@STRENGTH
* successfully set certificate verify locations:
*   CAfile: /usr/local/etc/openssl/cert.pem
  CApath: none
* TLSv1.2 (OUT), TLS header, Certificate Status (22):
} [5 bytes data]
* TLSv1.2 (OUT), TLS handshake, Client hello (1):
} [512 bytes data]
* TLSv1.2 (IN), TLS handshake, Server hello (2):
{ [102 bytes data]
* TLSv1.2 (IN), TLS handshake, Certificate (11):
{ [2478 bytes data]
* TLSv1.2 (IN), TLS handshake, Server key exchange (12):
{ [333 bytes data]
* TLSv1.2 (IN), TLS handshake, Server finished (14):
{ [4 bytes data]
* TLSv1.2 (OUT), TLS handshake, Client key exchange (16):
} [70 bytes data]
* TLSv1.2 (OUT), TLS change cipher, Client hello (1):
} [1 bytes data]
* TLSv1.2 (OUT), TLS handshake, Finished (20):
} [16 bytes data]
* TLSv1.2 (IN), TLS change cipher, Client hello (1):
{ [1 bytes data]
* TLSv1.2 (IN), TLS handshake, Finished (20):
{ [16 bytes data]
* SSL connection using TLSv1.2 / ECDHE-RSA-AES256-GCM-SHA384
* ALPN, server accepted to use h2
* Server certificate:
*  subject: CN=www.myexample.com
*  start date: Dec  4 17:26:21 2017 GMT
*  expire date: Mar  4 17:26:21 2018 GMT
*  issuer: C=US; O=Let's Encrypt; CN=Let's Encrypt Authority X3
*  SSL certificate verify ok.
* Using HTTP2, server supports multi-use
* Connection state changed (HTTP/2 confirmed)
* TCP_NODELAY set
* Copying HTTP/2 data in stream buffer to connection buffer after upgrade: len=0
} [5 bytes data]
* Using Stream ID: 1 (easy handle 0x7fb65d80aa00)
} [5 bytes data]


> GET /foo/bar/index.html HTTP/1.1
> Host: www.myexample.com
> User-Agent: curl/7.50.0
> Accept: */*
> Pragma: akamai-x-cache-on,akamai-x-cache-remote-on,akamai-x-check-cacheable,akamai-x-get-cache-key,akamai-x-get-extracted-values,akamai-x-get-request-id,akamai-x-serial-no, akamai-x-get-true-cache-key
>
{ [5 bytes data]
* Connection state changed (MAX_CONCURRENT_STREAMS updated)!
} [5 bytes data]


< HTTP/2 200
< content-type: text/html
< last-modified: Tue, 25 Apr 2017 08:22:18 GMT
< accept-ranges: bytes
< server: Apache
< x-check-cacheable: NO
< x-akamai-request-id: 1ebbab.12dc10
< x-akamai-transformed: 9 3538 0 pmb=mRUM,1
< date: Wed, 27 Dec 2017 06:45:15 GMT
< content-length: 4567
< x-cache: TCP_MISS from a23-48-169-52.deploy.akamaitechnologies.com (AkamaiGHost/9.1.4.4-21488373) (-)
< x-cache-key: S/D/98765/123456/000/www.myexample.com/space/foo/bar/index.html?akamai-transform=9
< x-true-cache-key: /D/000/www.myexample.com/space/foo/bar/index.html
< x-serial: 98765
< x-cache-remote: TCP_MISS from a23-50-62-39.deploy.akamaitechnologies.com (AkamaiGHost/9.1.4.4-21488373) (-)
< x-akamai-staging: ESSL
<
* Excess found in a non pipelined read: excess = 76 url = /foo/bar/index.html (zero-length body)
* Connection #0 to host www.myexample.com.edgekey-staging.net left intact

上記結果の通り,SSL handshake,リクエスト,レスポンスの過程が時系列順で表示されます.これにより,リクエストのどの過程で問題が起きているのかなど,詳細を調べることができます.

 

 

4. まとめ

今回紹介したcurlによるテスト方法は,ブラウザでテストできない場合や,アクセス制限などによってスプーフィングやリクエストヘッダを追加できない場合に非常に重宝します.さらに,テスト自動化などDevOpsを意識したワークフローではほぼ必須になります.今回の紹介したテスト方法をアカマイ化プロセスにおけるデバッグ手法・検証作業効率化のひとつのオプションとして実践されてみてはいかがでしょうか.

Outcomes