
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). Таким образом, чтобы иметь возможность установить безопасное соединение, вам нужно настроить ваш клиент (например, браузер) на доверие CA RITM.
По соображениям безопасности, каждый раз при запуске прокси RITM с настройками по умолчанию он генерирует новый внутренний Центр сертификации. Чтобы вместо этого использовать ваш собственный CA (чтобы он мог быть загружен и признан доверенным вашим браузером), выполните следующие шаги:
Вы можете использовать OpenSSL или RITM для генерации этих двух файлов. С помощью 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. Серфите в интернете!
Или очень хорошо позаботьтесь о закрытом ключе CA, поскольку любой, владеющий этим ключом, сможет расшифровать весь ваш трафик! Также обратите внимание, что при использовании прокси каждый сервер будет автоматически считаться доверенным, даже если сертификат конечного сервера недействителен.
В приведенных выше примерах мы использовали глобальный сеанс по умолчанию. Если вам не нравится использовать статически настроенный глобальный сеанс, или вы хотите иметь несколько сосуществующих сеансов (например, несколько прокси, слушающих разные порты и использующих разные обработчики перехвата), вы можете создать разные экземпляры сеансов следующим образом:
session = Ritm::Session.new
# Now you can use the same methods but on the session instance
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
Лицензировано на условиях Apache License, Version 2.0 ("Лицензия"); вы не можете использовать этот файл иначе, как в соответствии с Лицензией. Копию Лицензии можно получить по адресу
http://www.apache.org/licenses/LICENSE-2.0
Если это не требуется применимым законодательством или не согласовано в письменной форме, программное обеспечение, распространяемое по Лицензии, распространяется на условиях "AS IS", БЕЗ ГАРАНТИЙ ИЛИ УСЛОВИЙ ЛЮБОГО ВИДА, явных или подразумеваемых. См. Лицензию для получения информации об ограничениях ответственности и разрешениях.