简体   繁体   中英

Connect to a FTPS server with mismatched server certificate using Net::FTPTLS

I am trying to connect via Net::FTPTLS to a Microsoft-based file server (IIS) which is configured to use FTP on port 22 and requires SSL.

I connect via:

require 'net/ftptls'
ftp = Net::FTPTLS.new()
ftp.connect('host.com', port_number)
ftp.login('Username', 'Password')
ftp.puttextfile('somefile.txt', 'where/to/save/somefile.txt')
ftp.close

Problem is, I get the following error:

hostname does not match the server certificate

It seems that I have to disable the openssl peer verification: OpenSSL::SSL::VERIFY_PEER should become OpenSSL::SSL::VERIFY_NONE.

Any ideas on how to monkey-patch the Net::FTPTLS class? Has anyone done this successfully?

Instead using Net::FTPTLS, use Ruby 2.4+ with the following code:

require 'net/ftp'
ftp = Net::FTP.new(nil, ssl: {:verify_mode => OpenSSL::SSL::VERIFY_NONE})
ftp.connect('host.com', port_number)
ftp.login('Username', 'Password')
ftp.puttextfile('somefile.txt', 'where/to/save/somefile.txt')
ftp.close

What I did, rather than monkeypatching ruby itself, was bring a copy of this into /lib of my project.

module Net

  class FTPTLS < FTP
    def connect(host, port=FTP_PORT)
      @hostname = host
      super
    end

    def login(user = "anonymous", params = {:password => nil, :acct => nil, :ignore_cert => false})
      store = OpenSSL::X509::Store.new
      store.set_default_paths
      ctx = OpenSSL::SSL::SSLContext.new('SSLv23')
      ctx.cert_store = store
      ctx.verify_mode = params[:ignore_cert] ? OpenSSL::SSL::VERIFY_NONE : OpenSSL::SSL::VERIFY_PEER
      ctx.key = nil
      ctx.cert = nil
      voidcmd("AUTH TLS")
      @sock = OpenSSL::SSL::SSLSocket.new(@sock, ctx)
      @sock.connect
      @sock.post_connection_check(@hostname) unless params[:ignore_cert]
      super(user, params[:password], params[:acct])
      voidcmd("PBSZ 0")
    end
  end
end

I also cleaned up the param passing a bit. You would use this like so:

  require 'ftptls'  # Use my local version, not net/ftptls
  @ftp_connection = Net::FTPTLS.new()
  @ftp_connection.passive = true
  @ftp_connection.connect(host, 21)
  @ftp_connection.login('user', :password => 'pass', :ignore_cert => true)

HTH

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM