socksify-ruby icon indicating copy to clipboard operation
socksify-ruby copied to clipboard

FTP Connection with Ruby 2.4/2.5

Open dlahn opened this issue 7 years ago • 6 comments

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.

dlahn avatar Mar 14 '18 16:03 dlahn

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.

tritonrc avatar Jun 28 '18 15:06 tritonrc

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

dbackeus avatar Mar 18 '19 10:03 dbackeus

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 avatar May 22 '19 17:05 andrew-aladev

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.

andrew-aladev avatar May 22 '19 20:05 andrew-aladev

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!

joneszach avatar Nov 25 '20 00:11 joneszach

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

MathieuDerelle avatar Mar 25 '21 21:03 MathieuDerelle