1
votes

I'm busy with a curl php library which needs to connect to an FTPS server.

I have this semi working... If I connect to ftp://domain.com then it does work. If I watch the comms on the server with tcpflow I see it logging in with AUTH TLS and and all the comms is encrypted. The file is uploaded so all's good..

What I'm unsure of is if its valid to try connecting instead to ftps://domain.com?

The reason I'm asking is because if I change the protocol from ftp to ftps in curl then the login fails and the server (watching tcpflow comms) says that the login has failed:

191.101.002.204.00021-088.099.012.154.51630: 530 Please login with USER and PASS.

Also, when I watch the comms when trying to connect to ftps:// I don't see the client issuing the AUTH TLS command as it does with plain ftp://

The problem I have is that it seems that my client's FTP server we have to ultimately connect to doesn't seem to allow connections without the ftps:// protocol.

If I connect using lftp I can do so using ftps:// but then I have to disable ssl: set ftp://ssl-allow no

If I try the lftp connection using ftp:// it just hangs on the login command...

I'm not really that experienced with FTP or TLS / SSL so I don't know if its maybe because the client's server doesn't have the certificates set up correctly..

Here is a portion of my curl code which works with ftp:// but not ftps://

 // Works
 $url = "ftp://proxy.plettretreat.co.za/";
 // Does not work
 $url = "ftps://proxy.plettretreat.co.za/";
 $port = 990;
 $username = "ftpuser";
 $password = "pass";   

 $filename = "/test.php";
 $file = dirname(__FILE__)."/test.php";

 $c = curl_init();

 // check for successful connection
 if ( ! $c)
      throw new Exception( 'Could not initialize cURL.' );

 $options = array(
      CURLOPT_USERPWD        => $username.':'.$password,
      CURLOPT_SSL_VERIFYPEER =>     0,
      CURLOPT_SSL_VERIFYHOST =>     0,
      CURLOPT_RETURNTRANSFER =>     1,
      CURLOPT_BINARYTRANSFER =>     1,          
      CURLOPT_FTP_SSL        => CURLFTPSSL_ALL, // require SSL For both control and data connections
      CURLOPT_FTPSSLAUTH     => CURLFTPAUTH_TLS, // let cURL choose the FTP authentication method (either SSL or TLS)
      CURLOPT_UPLOAD         => true,
      CURLOPT_PORT           => $port,
      CURLOPT_TIMEOUT        => 30,
 );

Another thing I'm unsure of is that my client has given me an IP address to connect to.. Can an IP address be used in ftps? I would have thought that certificates are mostly certifying a domain name?

tl;dr

1) Can I use ftps://domain.com to connect using CURL PHP? 2) If I can use ftps:// in curl, then how do I get curl to log in (issue auth tls command)? 3) Can an FTP server use SSL / TLS with only an IP address?

Thanks...

John

1

1 Answers

0
votes

Many many hours of struggling led me to an eventual answer.

Part of the answer was that the client server and the FTP server had "overly" strict firewall rules blocking the passive ports.

I was getting the following error:

Error no: 35; Error: SSL connect error.

Error 35 was because of the firewall rules. Once those were relaxed that error went away, but as a note, you will also see this error if the client machine is NAT'ed. If it is you need to set the curl option:

curl_setopt($c, CURLOPT_FTPPORT, '1.2.4.5' ); // change to your actual IP.

This tells the FTP server where to open up its data channel (instead of trying to open it to the client server's internal address).

Anyway, once the firewall and FTPPORT options were set I got:

Error no: 30; Error: bind(port=0) failed: Cannot assign requested address

This one baffled me for quite a while as everything looked correct.

I eventually stumbled upon a few thread here and elsewhere which talk about an issue with older versions of Curl using NSS for its encryption. I checked and I was using libcurl version 7.19.7 (about 8 years old) and sure enough it uses NSS...

I updated my Curl using this guide: https://www.digitalocean.com/community/questions/how-to-upgrade-curl-in-centos6. That updated me to libcurl 7.52.1 which uses OpenSSL and lo and behold, my app started working...

So, if you're having issues connecting curl-ftp to a FTPS server, check the FTPPORT (passive IP) if you're NAT'ed, check your firewall, but most importantly, check your curl:

<?php
print print_r(curl_version());
?>

I hope this helps someone..