FTPS (TLS/SSL) from Ruby on Rails App

后端 未结 6 1876
清酒与你
清酒与你 2021-01-04 05:40

I have an FTP server which only accepts connections through running FTPS (explicit FTP over TLS). I need to be able to connect to this using a Ruby on Rails app.

相关标签:
6条回答
  • 2021-01-04 06:26

    If you want to use Implicit FTPS, please try this gist.

    For Explicit FTPs, you can use the ruby gem ftpfxp.

    0 讨论(0)
  • 2021-01-04 06:28

    I implemented an ftps solution using double-bag-ftps

    double-bag-ftps

    0 讨论(0)
  • 2021-01-04 06:36

    EDIT: I figured out how to get it running locally, but am having issues getting it to work on Heroku. That's a bit of a departure from this question, so I've created a new one:

    Heroku with FTPTLS - Error on SSL Connection

    require 'net/ftptls'
    ftp = Net::FTPTLS.new()
    ftp.passive = true
    #make sure you define port_number
    ftp.connect('host.com', port_number)
    ftp.login('Username', 'Password')
    ftp.gettextfile('filename.ext', 'where/to/save/file.ext')
    ftp.close
    
    0 讨论(0)
  • 2021-01-04 06:41

    How about using Net::FTPTLS ?

    0 讨论(0)
  • 2021-01-04 06:41

    I done something like this with Implicit/Explicit FTPS, I used double-bag-ftps gem that I patched to support reuse of ssl session. It's a requirement for a lot of ftps servers.

    I put the code on github here : https://github.com/alain75007/double-bag-ftps

    0 讨论(0)
  • 2021-01-04 06:47

    Since Ruby 2.4, TLS over FTP has been available with Net::FTP... this has caused gems like double-bag-ftps to become archived and all your google searches to yield outdated answers.

    If you can do explicit FTP over TLS (Connects to FTP normally, then issues a command AUTH TLS to switch to TLS Mode), then great... that should be able to use Ruby's Net::FTP out of the box by just passing {ssl: true} in the options.

    Implicit FTP over TLS (runs over TLS from the get-go) does not work out of the box, however, and you must override Net::FTP's connection method to establish an SSL socket and then optionally send commands to the FTP server.

    Inidka K posted a Github Gist, but since those are bad form (can go stale), I've posted my version that works against a ShareFile Implicit FTP setup (which seems to only support Implicit FTP):

    require 'net/ftp'
    
    class ExplicitFtp < Net::FTP
      FTP_PORT = 990
    
      def connect(host, port = FTP_PORT)
        synchronize do
          @host = host
          @bare_sock = open_socket(host, port)
          begin
            ssl_sock = start_tls_session(Socket.tcp(host, port))
            @sock = BufferedSSLSocket.new(ssl_sock, read_timeout: @read_timeout)
            voidresp
            if @private_data_connection
              voidcmd("PBSZ 0")
              voidcmd("PROT P")
            end
          rescue OpenSSL::SSL::SSLError, Net::OpenTimeout
            @sock.close
            raise
          end
        end
      end
    end
    

    Then, in your code:

    ftp_options = {
      port:    990,
      ssl:      true,
      debug_mode: true, # If you want to see what's going on
      username: FTP_USER,
      password: FTP_PASS
    }
    ftp = ExplicitFtp.open(FTP_HOST, ftp_options)
    puts ftp.list
    ftp.close
    
    0 讨论(0)
提交回复
热议问题