astro / socksify-ruby

Redirect any TCP connection initiated by a Ruby script through a SOCKS5 proxy
http://socksify.rubyforge.org/
Other
165 stars 80 forks source link

FTP Connection with Ruby 2.4/2.5 #34

Open dlahn opened 6 years ago

dlahn commented 6 years ago

We are currently using Socksify to proxy FTP connections through our SOCKS proxy. This has been working for years in Ruby 2.3 (and older versions.)

I've upgraded to Ruby 2.5 (and 2.4), and noticed that it no longer seems to proxy the FTP connections, while an HTTP connection will work fine. Here is some example code.

require 'socksify'
Socksify::debug = true
TCPSocket::socks_server = '...'
TCPSocket::socks_port = ...
require 'net/ftp'
require 'net/http'
Socksify::proxy('...', ...) do |soc|
  uri = URI('https://api.ipify.org?format=json')
  puts Net::HTTP.get(uri)
  ftp = Net::FTP.new
  ftp.debug_mode = true
  ftp.connect('...', 21)
end

With the above code, I can see in the debug that it connects to the SOCKS proxy, and then to the HTTP example using the SOCKS proxy, but it does not for the FTP connection. Downgrading to 2.3 shows the proper behaviour of both connecting through the SOCKS proxy.

tritonrc commented 6 years ago

I am encountering the same issue, digging into the Net::FTP source, I found this change: https://github.com/ruby/ruby/commit/73199e1e82b02cd0a9c487bbee533f4398755b19#diff-591012d50ff69129fec34f4f853eba9bR322

Where TCPSocket is changed to Socket, since Socksify monkey-patches TCPSocket the FTP code path no longer "sees" the Socksify code.

dbackeus commented 5 years ago

We have the same issue. Has anyone found a workaround or alternative option for proxying FTP connections?

andrew-aladev commented 5 years ago

The only one option is ruby 2.3.8. We have to rewrite it from scratch because API changed in 2.4 completely. I have no time to do it.

andrew-aladev commented 5 years ago

I've figured out how to use new native socks support.

rvm reinstall ruby-2.5.5 -C --enable-socks

It is required because default socks support is disabled.

require "net/ftp"

ENV["SOCKS_SERVER"] = "127.0.0.1:9050"

Net::FTP.open("ftp.byfly.by", :debug_mode => true) do |ftp|
  ftp.login
end

Start tor - it returns success, stop tor - it fails, ok. So if you want to update socksify - patch SOCKSSocket.

joneszach commented 4 years ago

I've figured out how to use new native socks support.

rvm reinstall ruby-2.5.5 -C --enable-socks

It is required because default socks support is disabled.

Start tor - it returns success, stop tor - it fails, ok. So if you want to update socksify - patch SOCKSSocket.

THANK YOU SO MUCH! I spent hours trying to figure out how to solve my problem with newer ruby not flawlessly working with socks5, and this recompile step worked perfectly!

MathieuDerelle commented 3 years ago

For people who can not compile ruby with additional features (on heroku for instance)

I've got an ok-ish workaround by subclassing Net::FTP and using the open_socket method from before this commit https://github.com/ruby/ruby/commit/73199e1e82b02cd0a9c487bbee533f4398755b19#diff-591012d50ff69129fec34f4f853eba9bR322

class Net::FTP::Socksifiable < Net::FTP
     def open_socket(host, port) # :nodoc:
       return Timeout.timeout(@open_timeout, Net::OpenTimeout) {
         if defined? SOCKSSocket and ENV["SOCKS_SERVER"]
           @passive = true
           sock = SOCKSSocket.open(host, port)
         else
           sock = TCPSocket.open(host, port)
         end
       }
     end
end