
耐障害性テストと疑似ネットワーク環境のためのハッキング可能なHTTPプロキシ
積極的にメンテナンスされていません。最新のNode.jsランタイムでは動作しない可能性があります。toxyのメンテナンスに興味がある場合は、Issueを開いてください。
ハッキング可能なHTTPプロキシで、サーバーの障害シナリオ、システムの耐障害性テスト、予期しないネットワーク状態をシミュレートするために、node.js用に構築されています。
これは主に障害耐性テストのために設計されており、toxyは特に耐遅延ネットワークやサービス指向アーキテクチャにおいて、システムの耐障害性と回復力の能力をカバーする際に特に有用です。そこではtoxyがサービス間でMitMプロキシとして機能し、障害を注入します。
toxyを使用すると、毒をプラグインでき、オプションでルールでフィルタリングできます。これらは本質的にHTTPフローを必要に応じて傍受および変更し、そのプロセスの途中で帯域幅の制限、ネットワークパケットの遅延、ネットワークジッタレイテンシの注入、カスタムエラーやステータスコードでの応答など、複数の悪質なアクションを実行できます。主にL7で動作しますが、L3のネットワーク状態をシミュレートすることもできます。
toxyはプログラムによるAPIまたはHTTP APIを介して流暢に使用できます。 これはrocky(フル機能のミドルウェア指向HTTPプロキシ)上に構築されており、connect/expressに標準ミドルウェアとしてプラグイン可能です。
Node.js +4 が必要です。
市場にはtoxyに似たソリューションがいくつか存在しますが、それらのほとんどは適切なプログラムによる制御を提供しておらず、通常はハッキングや設定が容易ではないか、拡張性に対して閉じています。
さらに、それらのソリューションの大部分は、特定のドメインとHTTP L7プロトコルの性質における一般的な要件をカバーするための高レベルの抽象化を提供する代わりに、TCP L3レベルスタックでのみ動作します。toxyはそれを提供しようとしています。
toxyは、便利な抽象化を備えた強力でハッキング可能かつ拡張可能なソリューションを提供しますが、HTTPプロトコルのプリミティブを簡単に扱うための適切な低レベルインターフェースの機能を失うことはありません。
toxyは、構成、シンプルさ、拡張性の原則に基づいて設計されました。 組み込みの階層的なドメイン固有ミドルウェア層を介して、toxyの機能を独自のニーズに合わせて簡単に拡張できます。
toxyは2つのディレクティブを導入します: 毒とルール。
毒は、着信または発信のHTTPトランザクションに影響を与える(例:レイテンシの注入、エラーでの応答)特定のロジックです。1つのHTTPトランザクションは1つまたは複数の毒によって影響を受ける可能性があり、それらの毒はグローバルトラフィックまたはルートレベルトラフィックの両方に影響を与えるように構成することもできます。
ルールは、HTTPリクエスト/レスポンスを検査して、特定のルールに基づいてHTTPトランザクションに毒を適用するかどうかを判断する(例:ヘッダーが一致するか、クエリパラメータ、メソッド、ボディ...)一種のマッチ検証フィルターです。ルールは再利用可能であり、異なるスコープ(グローバル、ルート、毒レベル)を含む着信および発信のトラフィックフローの両方に適用できます。
↓ ( Incoming request ) ↓ ↓ ||| ↓ ↓ +-------------+ ↓ ↓ | Toxy Router | ↓ -> Match the incoming request ↓ +-------------+ ↓ ↓ ||| ↓ ↓ +--------------------+ ↓ ↓ | Incoming phase | ↓ -> The proxy receives the request from the client ↓ |~~~~~~~~~~~~~~~~~~~~| ↓ ↓ | ---------------- | ↓ ↓ | | Exec Rules | | ↓ -> Apply configured rules for the incoming request ↓ | ---------------- | ↓ ↓ | ||| | ↓ ↓ | ---------------- | ↓ ↓ | | Exec Poisons | | ↓ -> If all rules passed, then poison the HTTP flow ↓ | ---------------- | ↓ ↓ +~~~~~~~~~~~~~~~~~~~~+ ↓ ↓ / \ ↓ ↓ \ / ↓ ↓ +--------------------+ ↓ ↓ | HTTP dispatcher | ↓ -> Forward the HTTP traffic to the target server, either poisoned or not ↓ +--------------------+ ↓ ↓ / \ ↓ ↓ \ / ↓ ↓ +--------------------+ ↓ ↓ | Outgoing phase | ↓ -> Receives response from target server ↓ |~~~~~~~~~~~~~~~~~~~~| ↓ ↓ | ---------------- | ↓ ↓ | | Exec Rules | | ↓ -> Apply configured rules for the outgoing request ↓ | ---------------- | ↓ ↓ | ||| | ↓ ↓ | ---------------- | ↓ ↓ | | Exec Poisons | | ↓ -> If all rules passed, then poison the HTTP flow before send it to the client ↓ | ---------------- | ↓ ↓ +~~~~~~~~~~~~~~~~~~~~+ ↓ ↓ ||| ↓ ↓ ( Send to the client ) ↓ -> Finally, send the request to the client, either poisoned or not
## 使用方法
### インストール```
npm install toxy
より多くのユースケースについては、examples ディレクトリを参照してください。```js var toxy = require('toxy') var poisons = toxy.poisons var rules = toxy.rules
// Create a new toxy proxy var proxy = toxy()
// Default server to forward incoming traffic proxy .forward('http://httpbin.org')
// Register global poisons and rules proxy .poison(poisons.latency({ jitter: 500 })) .rule(rules.probability(25))
// Register multiple routes proxy .get('/download/') .forward('http://files.myserver.net') .poison(poisons.bandwidth({ bps: 1024 })) .withRule(rules.headers({'Authorization': /^Bearer (.)$/i }))
// Infect outgoing traffic only (after the server replied properly) proxy .get('/image/*') .outgoingPoison(poisons.bandwidth({ bps: 512 })) .withRule(rules.method('GET')) .withRule(rules.timeThreshold({ duration: 1000, threshold: 1000 * 10 })) .withRule(rules.responseStatus({ range: [ 200, 400 ] }))
proxy .all('/api/*') .poison(poisons.rateLimit({ limit: 10, threshold: 1000 })) .withRule(rules.method(['POST', 'PUT', 'DELETE'])) // And use a different more permissive poison for GET requests .poison(poisons.rateLimit({ limit: 50, threshold: 1000 })) .withRule(rules.method('GET'))
// Handle the rest of the traffic proxy .all('/*') .poison(poisons.slowClose({ delay: 1000 })) .poison(poisons.slowRead({ bps: 128 })) .withRule(rules.probability(50))
proxy.listen(3000) console.log('Server listening on port:', 3000) console.log('Test it:', 'http://localhost:3000/image/jpeg')
## ベンチマーク
詳細は [toxy/benchmark](https://github.com/h2non/toxy/tree/master/benchmark) を参照してください。
## ポイズン
ポイズンは、プロキシサーバー内のHTTPトランザクションをインターセプトして変更、ラップ、修正、またはキャンセルする特定のロジックを提供します。ポイズンは、受信トラフィック、送信トラフィック、またはその両方に適用できます([ポイズンフェーズ](#poisoning-phases)を参照)。
ポイズンは、さまざまなHTTPシナリオに対して合成および再利用できます。これらはFIFO順で非同期に実行されます。
### ポイズニングスコープ
`toxy` は、`global` と `route` という2つの異なるスコープに基づく階層設計を採用しています。
**グローバル** スコープは、HTTPメソッドやパスに関係なく、プロキシサーバーが受信するすべての受信HTTPトラフィックを対象とします。
**ルート** スコープは、特定のHTTPメソッドとURIパスに一致する受信トラフィックを対象とします。
ポイズンは両方のスコープに接続できるため、より正確に操作し、ポイズニングの範囲を制限できます。例えば、特定のルート(`/download` や `/images` など)にのみ帯域幅制限ポイズンを適用したい場合などです。