
Ruby In The Middle (HTTP/HTTPS インターセプションプロキシ)
Ruby in the middle (RITM) は、HTTP/HTTPS インターセプションプロキシです。オンフライでの証明書生成と署名を行い、ユーザーは Ruby 言語の全機能を駆使して、リクエストやレスポンスを自由に傍受・改変できます。
gem install ritm
require 'ritm'
# A single answer for all your google searches
Ritm.on_request do |req|
if req.request_uri.host.start_with? 'www.google.'
new_query_string = req.request_uri.query.gsub(/(?<=^q=|&q=)(((?!&|$).)*)(?=&|$)/, 'RubyInTheMiddle')
req.request_uri.query = new_query_string
end
end
my_picture = File.read('i_am_famous.jpg')
# Replaces every picture on the web with my pretty face
Ritm.on_response do |_req, res|
if res.header['content-type'] && res.header['content-type'].start_with?('image/')
res.header['content-type'] = 'image/jpeg'
res.body = my_picture
end
end
Ritm.start
puts 'Hit enter to finish'
gets
Ritm.shutdown
または、トラフィックを傍受したい任意の HTTP クライアントを、localhost:8080 のプロキシに接続するように設定します。
上記の例では、Google で何かを検索したり、お気に入りの新聞サイトを訪れてみてください。
前述の例では、HTTPS リソースにアクセスしようとした際に、クライアントで問題が発生する可能性があります。ブラウザに例外を追加したり、HTTP クライアントに証明書検証をスキップするよう指示できる場合もありますが、例外を追加できない場合もあります。その理由は、SSL トラフィックを復号・改変可能にするために、RITM がクライアントとの SSL ネゴシエーションを(自身の証明書を使って)行い、その後サーバーに対して別の SSL セッションを確立する必要があるためです。すなわち:
Client <--- SSL session ---> RITM <--- SSL session ---> Server
クライアントが通信しようとするサーバーのホスト名ごとに、RITM はその場で証明書を生成し、あらかじめ設定された認証局 (CA) で署名します。そのため、安全な接続を確立するには、クライアント(ブラウザなど)に RITM の CA を信頼するよう設定する必要があります。
セキュリティ上の理由から、デフォルト設定で RITM のプロキシを起動するたびに、新しい内部認証局が生成されます。代わりに独自の CA を使用する(ブラウザにロードして信頼させる)には、以下の手順を実行してください。
OpenSSL または RITM を使用してこれら2つのファイルを生成できます。OpenSSL の場合:
openssl req -new -nodes -x509 -days 365 -extensions v3_ca -keyout insecure_ca.key -out insecure_ca.crt
または RITM の場合:
require 'ritm/certs/ca'
ca = Ritm::CA.create common_name: 'InsecureCA'
File.write('insecure_ca.crt', ca.pem)
File.write('insecure_ca.key', ca.private_key.to_s)
Ritm.configure do
ssl_reverse_proxy.ca[:pem] = 'path/to/insecure_ca.crt'
ssl_reverse_proxy.ca[:key] = 'path/to/insecure_ca.key'
end
Ritm.start
puts 'Hit enter to finish'
gets
Ritm.shutdown
これをブラウザやクライアントでどのように行うかは、ご自身でお調べください。 4. Web を閲覧する!
または、CA の秘密鍵を厳重に管理してください。その鍵を入手した者は、あなたのすべてのトラフィックを復号できてしまいます。また、プロキシを使用している間は、接続先サーバーの証明書が無効であっても、すべてのサーバーが自動的に信頼されることに注意してください。
上記の例では、デフォルトのグローバルセッションを使用していました。静的に設定されたグローバルセッションを使いたくない場合や、複数のセッションを共存させたい場合(例:異なるポートでリッスンし、異なるインターセプションハンドラを使用する複数のプロキシ)は、次のようにして異なるセッションインスタンスを作成できます。
session = Ritm::Session.new
# セッションインスタンスでも同じメソッドを使用できます
session.configure { proxy[:bind_port] = 7777 }
session.on_request { |req| ...do something here ... }
another_session = Ritm::Session.new
another_session.configure { proxy[:bind_port] = 8888 }
another_session.on_request { |req| ...do something else ... }
session.start
another_session.start
puts 'Hit enter to finish'
gets
session.shutdown
another_session.shutdown
Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.