Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

CURL FTP Connection refused only on hosting

Tags:

php

curl

ssl

ftp

I use PHP and Curl to connect to a FTP Server, the weird thing is that when i try my code in my local setup, it works in both implicit TLS and Explicit TLS way, but when i run the same code on any server it doesn't work and returns Connection refused.

The PHP code is:

<?php

function simple_list_test() {
    $curlopts = [];
    $debug = true;
    $return = null;
    
    $curlopts[CURLOPT_USERPWD] = "{$user}:{$password}";
    $curlopts[CURLOPT_SSL_VERIFYPEER] = false;
    $curlopts[CURLOPT_SSL_VERIFYHOST] = false;
    $curlopts[CURLOPT_FTP_SSL] = CURLFTPSSL_TRY;
    $curlopts[CURLOPT_FTPSSLAUTH] = CURLFTPAUTH_TLS;
    $curlopts[CURLOPT_RETURNTRANSFER] = true;
    $curlopts[CURLOPT_URL] = "ftp://ftp.avidafinance.com:21/"; // I tried with ftps:// protocol too it works on local but not when you run it on a hosting
    $curlopts[CURLOPT_FTPLISTONLY] = 1;
    $curlopts[CURLOPT_UPLOAD] = 0;
    $curlopts[CURLOPT_RETURNTRANSFER] = 1;

    $ch = curl_init();

    foreach($curlopts as $key => $value) {
        curl_setopt($ch, $key, $value);
    }

    if ($debug) {
        curl_setopt($ch, CURLOPT_VERBOSE, true);
        $verbose = fopen('php://temp', 'w+');
        curl_setopt($ch, CURLOPT_STDERR, $verbose);
    }

    $return = curl_exec($ch);

    if ($debug) {
        rewind($verbose);
        $verboseLog = stream_get_contents($verbose);
        echo "Verbose information:\n<pre>", htmlspecialchars($verboseLog), "</pre>\n";
    }

    if ($error = curl_error($ch)) {
        throw new Exception($error);
    }

    return $return;
}

I spent an entire day, trying so many methods including setting CURLOPT_PORT , setting ftps:// protocol, increasing timeout, including the server .crt and .pem certificates with curl, but none of them worked so i was wondering if anyone can give me a hand here,

Here's a brief of verbose output on local dev environment with PHP 7.3 and curl 7.68.0:

*   Trying 13.53.118.182:21...
* TCP_NODELAY set
* Connected to ftp.avidafinance.com (13.53.118.182) port 21 (#0)
< 220 FileZilla Server 0.9.60 beta
> AUTH TLS
< 234 Using authentication type TLS
* successfully set certificate verify locations:
*   CAfile: /etc/ssl/certs/ca-certificates.crt
  CApath: /etc/ssl/certs
* SSL connection using TLSv1.2 / ECDHE-RSA-AES256-GCM-SHA384
* Server certificate:
*  subject: OU=Domain Control Validated; CN=ftp.avidafinance.com
*  start date: Mar 23 12:46:23 2020 GMT
*  expire date: Mar 23 12:46:23 2022 GMT
*  issuer: C=US; ST=Arizona; L=Scottsdale; O=GoDaddy.com, Inc.; OU=http://certs.godaddy.com/repository/; CN=Go Daddy Secure Certificate Authority - G2
*  SSL certificate verify ok.
> USER ****
< 331 Password required for *****
> PASS *****
< 230 Logged on
> PBSZ 0
< 200 PBSZ=0
> PROT P
< 200 Protection level set to P
> PWD
< 257 "/" is current directory.
* Entry path is '/'
* Request has same path as previous transfer
> EPSV
* Connect data stream passively
* ftp_perform ends with SECONDARY: 0
< 229 Entering Extended Passive Mode (|||57081|)
*   Trying 13.53.118.182:57081...
* TCP_NODELAY set
* Connecting to 13.53.118.182 (13.53.118.182) port 57081
* Connected to ftp.avidafinance.com (13.53.118.182) port 21 (#0)
> TYPE A
< 200 Type set to A
> NLST
< 150 Opening data channel for directory listing of "/"
* Maxdownload = -1
* Doing the SSL/TLS handshake on the data stream
* successfully set certificate verify locations:
*   CAfile: /etc/ssl/certs/ca-certificates.crt
  CApath: /etc/ssl/certs
* SSL re-using session ID
* SSL connection using TLSv1.2 / ECDHE-RSA-AES256-GCM-SHA384
* Server certificate:
*  subject: OU=Domain Control Validated; CN=ftp.avidafinance.com
*  start date: Mar 23 12:46:23 2020 GMT
*  expire date: Mar 23 12:46:23 2022 GMT
*  issuer: C=US; ST=Arizona; L=Scottsdale; O=GoDaddy.com, Inc.; OU=http://certs.godaddy.com/repository/; CN=Go Daddy Secure Certificate Authority - G2
*  SSL certificate verify ok.
* Remembering we are in dir ""
< 226 Successfully transferred "/"
* Connection #0 to host ftp.avidafinance.com left intact

But when i run the exact same code on a host ( tried more than 3 different servers ), it's gonna be like this :

*   Trying 13.53.118.182...
* TCP_NODELAY set
* Connected to ftp.avidafinance.com (13.53.118.182) port 21 (#0)
< 220 FileZilla Server 0.9.60 beta
> AUTH TLS
< 234 Using authentication type TLS
* Cipher selection: ALL:!EXPORT:!EXPORT40:!EXPORT56:!aNULL:!LOW:!RC4:@STRENGTH
* successfully set certificate verify locations:
*   CAfile: /etc/pki/tls/certs/ca-bundle.crt
  CApath: none
* SSL connection using TLSv1.2 / ECDHE-RSA-AES256-GCM-SHA384
* Server certificate:
*  subject: OU=Domain Control Validated; CN=ftp.avidafinance.com
*  start date: Mar 23 12:46:23 2020 GMT
*  expire date: Mar 23 12:46:23 2022 GMT
*  issuer: C=US; ST=Arizona; L=Scottsdale; O=GoDaddy.com, Inc.; OU=http://certs.godaddy.com/repository/; CN=Go Daddy Secure Certificate Authority - G2
*  SSL certificate verify ok.
> USER *****
< 331 Password required for ******
> PASS *****
< 230 Logged on
> PBSZ 0
< 200 PBSZ=0
> PROT P
< 200 Protection level set to P
> PWD
< 257 "/" is current directory.
* Entry path is '/'
> EPSV
* Connect data stream passively
* ftp_perform ends with SECONDARY: 0
< 229 Entering Extended Passive Mode (|||57093|)
*   Trying 13.53.118.182...
* TCP_NODELAY set
* Connecting to 13.53.118.182 (13.53.118.182) port 57093
* connect to 13.53.118.182 port 21 failed: Connection refused
* Failed to connect to ftp.avidafinance.com port 21: Connection refused
* Failed EPSV attempt. Disabling EPSV
> PASV
< 227 Entering Passive Mode (13,53,118,182,222,194)
*   Trying 13.53.118.182...
* TCP_NODELAY set
* Connecting to 13.53.118.182 (13.53.118.182) port 57026
* connect to 13.53.118.182 port 21 failed: Connection refused
* Failed to connect to ftp.avidafinance.com port 21: Connection refused
* Closing connection 0

In Short i need an Explicit FTP Over TLS connection, i tried with curl, ftp_ssl_connect fsockets, .... none of them worked, I would appreciate any help, it doesn't have to necessarily be with curl

like image 595
Amin Avatar asked Oct 26 '22 18:10

Amin


1 Answers

Let's sum up what's in here: https://slacksite.com/other/ftp.html

In active mode FTP the client connects from a random unprivileged port (N > 1023) to the FTP server's command port, port 21.

and

In passive mode FTP the client initiates both connections to the server, solving the problem of firewalls filtering the incoming data port connection to the client from the server. When opening an FTP connection, the client opens two random unprivileged ports locally (N > 1023 and N+1).

this works on your machine because of non-restrict port policy, good to know that this doesn't work on the server, where you can't just "open-up ports".

I had a similar issue and I solve that with Python ftputil library.

like image 134
MiPnamic Avatar answered Nov 13 '22 16:11

MiPnamic