ruby SSL代理(MITM)
我想代理SSL数据,在这种情况下是HTTPS 这是我的密码:ruby SSL代理(MITM),ruby,ssl,proxy,Ruby,Ssl,Proxy,我想代理SSL数据,在这种情况下是HTTPS 这是我的密码: begin server = TCPServer.open(on_demand_port) rescue Exception => e sleep 5 retry end sslContext = OpenSSL::SSL::SSLContext.new sslContext.verify_mode = OpenSSL::SSL::VERIFY_NONE begin ss
begin
server = TCPServer.open(on_demand_port)
rescue Exception => e
sleep 5
retry
end
sslContext = OpenSSL::SSL::SSLContext.new
sslContext.verify_mode = OpenSSL::SSL::VERIFY_NONE
begin
sslContext.cert = OpenSSL::X509::Certificate.new(File.open("#{Dir.pwd}/Cert/cert.pem"))
sslContext.key = OpenSSL::PKey::RSA.new(File.open("#{Dir.pwd}/Cert/key.pem"), "1234")
rescue Exception => e
sleep 5
retry
end
begin
sslServer = OpenSSL::SSL::SSLServer.new(server, sslContext)
rescue Exception => e
sleep 5
retry
end
while true
begin
threads << Thread.new(sslServer.accept) do |client| # Putting new connections into the thread pool
tcp_proxy(client, db_name, db_user, db_password, remote_host, remote_port, patterns)
end
rescue Exception => e
end
threads = threads.select { |t| t.alive? ? true : (t.join; false) }
while threads.size >= on_demand_max_threads
sleep 1
threads = threads.select { |t| t.alive? ? true : (t.join; false) }
end
end
现在,这在正常的TCP和HTTP中工作得很好,但是,当我在升级套接字时在SSL\HTTPS中使用它时,它开始变得非常慢,有时会超时
知道为什么吗 您必须小心读取和选择,因为读取是在SSL级别完成的,而选择是在TCP级别完成的 SSL将数据放入帧中,每个帧最多可包含16384字节。它需要从底层TCP套接字读取完整帧,然后SSL套接字上的读取才能从帧返回任何数据。这意味着,如果您有一个有效负载为4097字节的帧,则需要先从TCP套接字读取完整帧,然后才能从SSL套接字读取任何内容。如果只从SSL套接字读取4096个字节,它将返回前4096个字节,其余(1个字节)保留在SSL缓冲区中。如果随后使用select在TCP级别上检查新数据,它可能会阻塞,因为在TCP级别上没有未读数据,即使SSL缓冲区中仍然存在单个字节 有两种方法可以解决此问题:
- 如果SSL缓冲区中仍有数据,请使用
检查。如果有,请阅读它们,而不是进行选择pending
- 或者尝试每次读取至少16384字节,这是SSL帧的最大大小。我不确定ruby中的实现,但在Perl中,这种读取将只调用底层的
,它只从单个帧读取数据。因此,如果读取大小为16384字节,就不会有挂起的数据,您可以像现在一样调用selectSSL\u read
begin
begin
ssl_context = OpenSSL::SSL::SSLContext.new
ssl_context.verify_mode = OpenSSL::SSL::VERIFY_NONE
cert_store = OpenSSL::X509::Store.new
cert_store.set_default_paths
ssl_context.cert_store = cert_store
tcp_socket = TCPSocket.new(remote_host, remote_port)
server_socket = OpenSSL::SSL::SSLSocket.new tcp_socket, ssl_context
server_socket.sync_close = true
server_socket.connect
rescue Exception => e
client.close
end
while true
# Wait for data to be available on either socket.
(ready_sockets, dummy, dummy) = IO.select([client, server_socket])
begin
ready_sockets.each do |socket|
data = socket.readpartial(4096)
if socket == client
# Read from client, write to server.
server_socket.write data
server_socket.flush
else
# Read from server, write to client.
client.write data
client.flush
end
end
rescue Exception => e
end
end
rescue StandardError => e
end
begin
client.close
server_socket.close
rescue Exception => e
end