===========================
Part I. HTTP: ウェブの基盤#
Chapter 01. HTTP の概要#
キーワード:
- MIME, URIs, URLs, URNs
- トランザクション:
- GET
- PUT
- DELETE
- POST
- HEAD
- ステータスコード
- リクエスト / レスポンスメッセージ:
- スタートライン
- ヘッダー
- コンテンツタイプヘッダー
- コンテンツ長ヘッダー
- ボディ(オプション,<空行 (CRLF)> + < ボディ >)
- 接続:
- TCP/IP
- 接続、IP アドレス、ポート番号
- プロトコルバージョン:
- 0.9
- 1.0
- 1.0+
- 1.1
- 2.0(HTTP-NG)
- ウェブのアーキテクチャコンポーネント
- プロキシ
- キャッシュ(ウェブキャッシュ、またはキャッシングプロキシ)
- ゲートウェイ
- トンネル
- エージェント(ウェブブラウザなど)
Chapter 02. URLs とリソース#
スキーム(方法)、ホスト(場所)、パス(何)
[<scheme>://][<user>[:<password>]@]<host>[:<port>][/<path>][;<params>][?<query>][#<frag>]
- パラメータ(Parameters)、名前 / 値ペア。
- ベース URL:
<BASE>
HTML タグ。相対 URL を絶対 URL に変換 - エクスパンダマティック URL
- ホスト名の拡張(
www.
.com
など) - 履歴の拡張
- ホスト名の拡張(
- 不正な文字
Chapter 03. HTTP メッセージ#
ポイント:
- トランザクションの方向:インバウンド、アウトバウンド
- メッセージの流れ:アップストリーム、ダウンストリーム
- メッセージの構文
- リクエストメッセージ
<method> <request-URL> <version> <headers> <entity-body>
- レスポンスメッセージ
<version> <status-code> <reason-phrase> <headers> <entity-body>
- ?
- バージョン 2.22 > 2.3
- ヘッダーの継続行
- メソッド: GET, PUT, POST, TRACE, OPTIONS, DELETE
- UA(ユーザーエージェント): UA-OS, UA-CPU など
- ヘッダー
- 一般ヘッダー: Date: Tue, 3 Oct 1974 02:16:00 GMT
- リクエストヘッダー: Accept: /
- Accept ヘッダー
- 条件付きリクエストヘッダー
- リクエストセキュリティヘッダー
- プロキシリクエストヘッダー
- レスポンスヘッダー: Server: Tiki-Hut/1.0
- エンティティヘッダー: Content-Type: text/html; charset=iso-latin-1
- コンテンツヘッダー
- エンティティキャッシングヘッダー
- 拡張ヘッダー:
- リクエストメッセージ
参照:
Chapter 04. 接続管理#
TCP 信頼性データパイプ
TCP ストリームは IP パケットによってセグメント化されて送信される
TCP 接続を整理する
TCP 接続
<source-IP-address, source-port, destination-IP-address, destination-port>
- TCP ソケットを使用したプログラミング
- s = socket(): 新しい名前のない未接続のソケットを作成します。
- bind(s, ): ソケットにローカルポート番号とインターフェースを割り当てます。
TCP パフォーマンスの考慮事項
- HTTP トランザクションの遅延
- パフォーマンスの焦点領域
- 遅延確認応答
- TCP スロースタート
- ネイグルのアルゴリズムと TCP_NODELAY
- TIME_WAIT の蓄積とポート枯渇
- シリアルトランザクションの遅延
並列接続
- 並列接続はページの読み込みを速くするかもしれません
- 並列接続は常に速いわけではありません
- 並列接続は「速く感じる」かもしれません
持続的接続
持続的接続と並列接続の違い
HTTP/1.0 + キープアライブ接続
- キープアライブ操作
- キープアライブとダムプロキシ
- 接続ヘッダーと盲目的リレー
- プロキシとホップバイホップヘッダー
プロキシ接続ハック
HTTP/1.1 持続的接続
パイプライン接続
接続終了の謎
- 「任意の時点で」の切断
- コンテンツ長と切り捨て
- 接続終了の許容、再試行、冪等性
- 優雅な接続終了
参照:
- http://www.w3.org/Protocols/HTTP/Performance/
- http://www.acm.org/sigcomm/ccr/archive/2001/jan01/ccr-200101-mogul.pdf
Part II. HTTP アーキテクチャ#
Chapter 05. ウェブサーバー#
ウェブサーバーの実装: HTTP, TCP
汎用ソフトウェアウェブサーバー
ウェブサーバーアプライアンス
組み込みウェブサーバー
実際のウェブサーバーの機能
* ステップ 1: クライアント接続の受け入れ
* 新しい接続の処理
* クライアントホスト名の識別(逆 DNS)
* ident を通じてクライアントユーザーを特定
* ステップ 2: リクエストメッセージの受信
* メッセージの内部表現
* 接続入出力処理アーキテクチャ
* ステップ 3: リクエストの処理
* ステップ 4: リソースのマッピングとアクセス
* ドキュメントルート(document root)
* 仮想ホストされたドキュメントルート
xml <VirtualHost www.marys-antiques.com> ServerName www.marys-antiques.com DocumentRoot /docs/mary TransferLog /logs/mary.access_log ErrorLog /logs/mary.error_log </VirtualHost>
* ユーザーホームディレクトリのドキュメントルート(GET /~Bob/index.html
==> /home/Bob/index.html)
* ディレクトリリスト
* 動的コンテンツリソースマッピング
ScriptAlias /cgi-bin/ /usr/local/etc/httpd/cgi-programs/ AddHandler cgi-script .cgi
* サーバーサイドインクルード(SSI)
* アクセス制御
* ステップ 5: レスポンスの構築
* レスポンスエンティティ
* MIME タイプ
* mime.types
* マジックタイプ
* 明示的タイプ(ファイル拡張子やコンテンツを無視)
* タイプネゴシエーション
* リダイレクション
* 永続的 / 一時的に移動したリソース
* URL の増強
* 負荷分散
* ステップ 6: レスポンスの送信
* ステップ 7: ロギング
Chapter 06. プロキシ#
ウェブ中間者
プライベートおよび共有プロキシ
プロキシ(仲介者)対ゲートウェイ(プロトコル変換)
プロキシを使用する理由は?
- 子供フィルター
- ドキュメントアクセスコントローラー
- セキュリティファイアウォール
- ウェブキャッシュ
- サロゲート
- コンテンツルーター
- トランスコーダー(
*.gif
==>*.jpeg
など) - 匿名化
プロキシはどこに行くのか?
プロキシサーバーの展開
* イーグレスプロキシ(成人向けコンテンツ)
* アクセス(イングレス)プロキシ(ISP アクセスプロキシ:ダウンロード速度)
* サロゲート
* ネットワーク交換プロキシ
プロキシ階層
- インバウンド
- アウトバウンド
- 親
- プロキシ階層コンテンツルーティング
プロキシがトラフィックを取得する方法
- クライアントを変更する(プロキシプラグイン)
- ネットワークを変更する(インターセプトプロキシ、GFW のように)
- DNS 名前空間を変更する
- ウェブサーバーを変更する
クライアントプロキシ設定
-
手動設定
-
ブラウザの事前設定
-
プロキシ自動設定:プロキシ自動設定(PAC)
- サフィックス: ".pac"
- MIME タイプ: "application/x-ns-proxy-autoconfig"
-
クライアントプロキシ設定:ウェブプロキシ自動発見プロトコル(WPAD)
- 動的ホスト発見プロトコル(DHCP)
- サービスロケーションプロトコル(SLP)
- DNS の既知ホスト名
- DNS SRV レコード
- DNS サービス URI を TXT レコードに
-
プロキシリクエストに関するトリッキーなこと
- プロキシ URI はサーバー URI と異なる
- サーバーリクエスト、明示的プロキシリクエスト、サロゲート(リバースプロキシ)リクエスト、インターセプトプロキシリクエスト
-
バーチャルホスティングに関する同じ問題(index.html ==> bob/index.html? または tom/index.html?)
-
インターセプトプロキシは部分的な URI を取得する
-
プロキシはプロキシリクエストとサーバーリクエストの両方を処理できる
-
フライト中の URI 変更
- URI クライアント自動拡張とホスト名解決
- プロキシなしの URI 解決
- 明示的プロキシによる URI 解決
- インターセプトプロキシによる URI 解決
メッセージのトレース
- Via ヘッダー
- Via 構文
- Via リクエストとレスポンスのパス
- Via とゲートウェイ
- サーバーと Via ヘッダー
- Via のプライバシーとセキュリティの影響
- TRACE メソッド
- Max-Forwards
プロキシ認証
プロキシ相互運用性
サポートされていないヘッダーとメソッドの処理
- OPTIONS: オプション機能サポートの発見
Allow ヘッダー
Chapter 07. キャッシング#
冗長なデータ転送
帯域幅のボトルネック
フラッシュクラウド
距離遅延
ヒットとミス(ヒット、ミス、再検証(新鮮さチェック))
- キャッシュヒット
- キャッシュミス
- 再検証ヒット(遅いヒット)
- 再検証ミス
If-Modified-Since で再検証リクエスト
- ==> 再検証ヒット: 304(未変更)レスポンス(「まだ新鮮」)
- ==> 再検証ミス:通常の HTTP 200 OK レスポンス + 完全なコンテンツ
ヒット率 / 比率(リクエストの割合)
バイトヒット率
ヒットとミスの区別
キャッシュトポロジー
- プライベートキャッシュ(Firefox:
about:cache
) - 共有パブリックキャッシュ(パブリックプロキシキャッシュ)
プロキシキャッシュ階層
キャッシュメッシュ、コンテンツルーティング、およびピアリング(兄弟キャッシュ)
キャッシュ処理ステップ
- ステップ 1: 受信
- ステップ 2: パース
- ステップ 3: ルックアップ
- ステップ 4: 新鮮さチェック
- ステップ 4: 新鮮さチェック
- ステップ 5: レスポンス作成
- ステップ 6: 送信
- ステップ 7: ロギング
キャッシュ処理フローチャート
コピーを新鮮に保つ
- ドキュメントの有効期限
- Cache-Control: max-age=<max-age(in seconds)>
- Expires:
- サーバー再検証
- 条件付きメソッドによる再検証(条件付きリクエスト)
- If-Modified-Since:
- If-None-Match: ETags(エンティティタグ)
弱いおよび強いバリデーター
エンティティタグと最終変更日を使用するタイミング
キャッシュ可能性の制御
- No-Cache および No-Store レスポンスヘッダー
- Cache-Control: no-store
- Cache-Control: no-cache #(ローカルにキャッシュされる可能性あり)
- Pragma: no-cache
- Max-Age レスポンスヘッダー
- Cache-Control: max-age=3600
- Cache-Control: s-maxage=3600 # 共有(パブリック)キャッシュ
- Expires レスポンスヘッダー
- Expires:
- Must-Revalidate レスポンスヘッダー
- Cache-Control: must-revalidate
- ヒューリスティック有効期限
- LM-Factor アルゴリズム
- クライアント新鮮さ制約
- Max-Age レスポンスヘッダー
- クライアント新鮮さ制約
キャッシュ制御の設定
- Apache で HTTP ヘッダーを制御
- mod_headers(mod_headers モジュール)
<Files *.html> Header set Cache-control no-cache </Files>
- mod_expires
- ExpiresDefault M86400
- ExpiresByType text/html "変更から 2 日 6 時間 12 分"
- mod_cern_meta
- mod_headers(mod_headers モジュール)
- HTTP-EQUIV を通じた HTML キャッシングの制御
詳細なアルゴリズム
- 年齢と新鮮さの寿命
- 年齢計算
- 明示的年齢は Date ヘッダーに基づく
- ホップバイホップ年齢計算
- ネットワーク遅延の補正
- 新鮮さ寿命計算
...
キャッシュと広告
- 広告主のジレンマ
- 出版社の応答(キャッシュバスティング)
ログ移行
Chapter 08. 統合ポイント:ゲートウェイ、トンネル、およびリレー#
クライアントサイドおよびサーバーサイドゲートウェイ
/
プロトコルゲートウェイ
- HTTP/*: サーバーサイドウェブゲートウェイ
- HTTP/HTTPS: サーバーサイドセキュリティゲートウェイ
- HTTPS/HTTP: クライアントサイドセキュリティアクセラレータゲートウェイ
リソースゲートウェイ
- コモンゲートウェイインターフェース(CGI)
- サーバー拡張 API
アプリケーションインターフェースとウェブサービス
トンネル
- CONNECT を使用して HTTP トンネルを確立(生のバイトリレー)
- CONNECT リクエスト
CONNECT home.netscape.com:443 HTTP/1.0
User-agent: Mozilla/4.0 - CONNECT レスポンス
- データトンネリング、タイミング、および接続管理
- SSL トンネリング
- SSL トンネリング対 HTTP/HTTPS ゲートウェイ
- トンネル認証
- トンネルセキュリティの考慮事項
リレー
Chapter 09. ウェブロボット#
クローラーとクローリング
どこから始めるか: 「ルートセット」
- 取り残された — 孤立した、
リンクを抽出し、相対リンクを正規化する
- ループと重複
パンくずの跡
- ツリーとハッシュテーブル
- ロスのあるプレゼンスビットマップ
- チェックポイント
- パーティショニング
エイリアスとロボットサイクル
- URL の正規化
- ファイルシステムリンクサイクル
- 動的バーチャルウェブスペース
ループと重複を避ける
- URL の正規化
- 幅優先クローリング
- スロットリング
- URL サイズの制限
- URL / サイトのブラックリスト
- パターン検出(
/subdir/subdir/subdir...
) - コンテンツフィンガープリンティング
- 人間の監視
ロボティック HTTP
- リクエストヘッダーの特定
- バーチャルホスティング
- 条件付きリクエスト
- レスポンス処理
- ステータスコード
- エンティティ
- ユーザーエージェントターゲティング
不適切なロボット
- 制御不能なロボット
- 古い URL
- 長くて間違った URL
- うるさいロボット
- 動的ゲートウェイアクセス
ロボットの除外
- ロボット排除標準(robots.txt)
- ウェブサイトと robots.txt ファイル
robots.txt
を取得し、レスポンスコードを確認- robots.txt ファイル形式
User-Agent: <robot-name> # ロボットの名前の大文字小文字を区別しない部分文字列
- Disallow/Allow プレフィックスの一致
- その他の robots.txt の知恵
robots.txt のキャッシュと有効期限
ロボット排除の Perl コード
HTML ロボット制御 META タグ
NOINDEX, NOFOLLOW, INDEX, FOLLOW, NOARCHIVE, ALL, NONE
ロボットエチケット
Chapter 10. HTTP-NG#
HTTP の成長痛
HTTP-NG アクティビティ = HTTP: 次世代(HTTP-NG)
モジュール化と強化
- レイヤー {1..3}
- 分散オブジェクト
- レイヤー 1: メッセージング(WebMUX)
- レイヤー 2: リモート呼び出し(バイナリワイヤプロトコル)
- レイヤー 3: ウェブアプリケーション
PART III. 識別、認証、およびセキュリティ#
Chapter 11. クライアント識別とクッキー#
個人的なタッチ
- HTTP ヘッダー
- クライアント IP アドレス
- ユーザーログイン(すぐにフレッドはインターネットをあきらめてオプラを見ることに戻るでしょう...)
- 太い URL
- 醜い URL
- URL を共有できない
- キャッシングを壊す
- 余分なサーバーロード
- エスケープハッチ(ショッピングカートを失う可能性があります)
- セッション間で持続しない
- クッキー
- クッキーの種類:セッションと持続的
- クッキーの動作
- クッキージャー:クライアントサイドの状態
- ドメイン
- allh
- パス
- セキュア
- 有効期限
- 名前
- 値
- 異なるサイトのための異なるクッキー(
Set-Cookie: key=val
, Cookie: key=value)
- クッキードメイン属性:
domain=<SITE>
、 例: "www.jianshu.com" - クッキーパス属性:
path=/autos/
- クッキーの成分
- バージョン 0(Netscape)クッキー
- バージョン 1(RFC 2965)クッキー
- クッキーとセッショントラッキング
- クッキーとキャッシング
- キャッシュできないドキュメントにマークを付ける
- Set-Cookie ヘッダーのキャッシングに注意
- Cookie ヘッダーを持つリクエストに注意
- クッキー、セキュリティ、およびプライバシー
Chapter 12. ベーシック認証#
- 認証
- 認証プロトコルとヘッダー
- セキュリティレルム
- ベーシック認証
- チャレンジ / レスポンス
- チャレンジ(server2client):
WWW-Authenticate: Basic realm=<quoted-realm>
- レスポンス(client2server):
Authorization: Basic <base64-username-and-password>
- Base-64 ユーザー名 / パスワードエンコーディング: BASE64ENC (:)
- プロキシ認証
ウェブサーバー | プロキシサーバー |
---|---|
認証されていないステータスコード: 401 | 認証されていないステータスコード: 407 |
WWW-Authenticate | Proxy-Authenticate |
Authorization | Proxy-Authorization |
Authentication-Info | Proxy-Authentication-Info |
- ベーシック認証のセキュリティの欠陥
Chapter 13. ダイジェスト認証#
ダイジェスト認証の改善
- トランスポート層セキュリティ(TLS)
- セキュア HTTP(HTTPS)
パスワードを秘密に保つためのダイジェストの使用
一方向ダイジェスト
-
ダイジェスト関数
のエイリアス =暗号的チェックサム
、一方向ハッシュ関数
、またはフィンガープリント関数
-
MD5
入力 | MD5 ダイジェスト |
---|---|
“Hi” | C1A5298F939E87E8F962A5EDFC206918 |
“bri!” | BEAAA0E34EBDB072F8627C038AB211F8 |
“3.1415926535897” | 475B977E19ECEE70835BC6DF46F4F6DE |
リプレイを防ぐためのノンスの使用
ノンス
と呼ばれる特別なトークン
ダイジェスト認証ハンドシェイク
- チャレンジ、ノンス、アルゴリズム...
ダイジェスト計算#
ダイジェストアルゴリズム入力データ
ダイジェストは 3 つのコンポーネントから計算される:
- 一方向ハッシュ関数 H (d) とダイジェスト KD (s,d) からなる関数のペア、ここで s は秘密を、d はデータを表す
- 秘密のパスワードを含むセキュリティ情報を含むデータのチャンク、A1 と呼ばれる
- リクエストメッセージの非秘密属性を含むデータのチャンク、A2 と呼ばれる
データの 2 つの部分、A1 と A2 は H と KD によって処理されてダイジェストを生成する。
H() = MD5()
KD(,) = H(concatenate(:))
qop: 保護の質
: HTTP リクエストメソッド
: リクエストラインからのリクエスト URI
nc: ノンスカウント
セキュリティ関連データ (A1)
アルゴリズム | A1 |
---|---|
MD5 | A1 = :: |
MD5-sess | A1 = MD5(::):: |
メッセージ関連データ (A2)
| qop | A2 |
| undefined | : |
| auth | : |
| auth-int | :() |
全体のダイジェストアルゴリズム
- 古いおよび新しいダイジェストアルゴリズム
| qop | ダイジェストアルゴリズム | ノート |
| :---: | :---: | :---: |
| undefined | KD(H(A1), (A2)) | 非推奨 |
| auth または auth-int | KD (H (A1), :::(A2)) | 推奨 | - 展開されたダイジェストアルゴリズムのチートシート
| qop | アルゴリズム | 展開されたアルゴリズム |
| :---: | :---: | :---: |
| undefined | , MD5, MD5-sess | MD5(MD5(A1):(A2)) |
| auth | , MD5, MD5-sess | MD5(MD5(A1)::::(A2)) |
| auth-int | , MD5, MD5-sess | MD5(MD5(A1)::::(A2)) |
ダイジェスト認証セッション
先制的認証
- 次のノンスの事前生成
- 限定的なノンスの再利用
- 同期されたノンス生成
ノンスの選択
- RFC 2617 で提案された、ノンス = BASE64 (time-stamp H (time-stamp ":" ETag ":" private-key))
- ETag: リクエストされたエンティティに関連付けられた HTTP ETag ヘッダー
対称認証
- アルゴリズムによる A2 の定義(リクエストダイジェスト)
| qop | A2 |
| :---: | :---: |
| undefined | : |
| auth | : |
| auth-int | :() | - アルゴリズムによる A2 の定義(レスポンスダイジェスト)
| qop | A2 |
| :---: | :---: |
| undefined | : |
| auth | : |
| auth-int | :() |
保護の質の向上
- qop の使用はオプションですが、古い RFC 2069 仕様との後方互換性のためのみです。
メッセージ整合性保護
ダイジェスト認証ヘッダー
実用的な考慮事項
- 複数のチャレンジ
- エラーハンドリング
- 保護スペース
- URI の書き換え
- キャッシュ
セキュリティの考慮事項
- ヘッダーの改ざん
- リプレイ攻撃
- 複数の認証メカニズム
- 辞書攻撃
- 敵対的プロキシと中間者攻撃
- 選択された平文攻撃
- パスワードの保存
Chapter 14. セキュア HTTP#
HTTP を安全にする
HTTPS
デジタル暗号化:秘密のコーディングの技術と科学
暗号
対称鍵暗号
- (e=k)、エンコーディング = デコーディング
- P = D(C, d)
- DES、Triple-DES、RC2、および RC4
- 鍵の長さと列挙攻撃