FTPS (TLS/SSL) from Ruby on Rails App

后端 未结 6 1910
清酒与你
清酒与你 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: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
    

提交回复
热议问题