"php_connect_nonb() failed: Operation now in progress (115)" with TLS/SSL-encrypted FTP connection in PHP - Unencypted connection works

11,895

Solution 1

The similar behavior of PHP code and curl suggests that a firewall is blocking a data connection.

As unencrypted connection works, it's probable that the firewall is being "smart" by monitoring FTP control connections and automatically forwarding data connection ports found in the control connection. But that cannot work for encrypted sessions, as the firewall cannot monitor them.

See also the "Smart Firewalls/NATs" section of my guide about network set up for FTP.

If you need to allow encrypted connection, you will need to talk to the server administrator.

Solution 2

ftp_set_option($ftpconn, FTP_USEPASVADDRESS, false);

This line of code before setting passivity of the connection ftp_pasv($ftpconn, true); saved my life.

Solution 3

i had same problem, fixed by add ftp server ip to firewall allow ip list

Share:
11,895

Related videos on Youtube

Daniel P.
Author by

Daniel P.

Updated on September 16, 2022

Comments

  • Daniel P.
    Daniel P. over 1 year

    I'm trying to use an automatic backup script for cPanel accounts of my server.
    I have mounted an FTP server in one local machine with FileZilla Server. I can connect and transfer files successfully with FileZilla client, a Plesk server, and lftp...
    The server only accepts encrypted connections and passive mode is enabled.

    For some unknown reason when trying to connect and put files with PHP the response is:

    Warning: ftp_put(): php_connect_nonb() failed: Operation now in progress (115) in
    /home/xxxxxxx/public_html/lab/test/perform_mysql_bk.php on line 326

    Any ideas for this error?

    For the connection I'm using:

    $fSuccess = false;
    
    $sServerAddress = $this->m_aConfig['FTP_SERVER_ADDRESS'];
    $iServerPort = (int)( $this->m_aConfig['FTP_SERVER_PORT'] );
    
    // set up FTP connection
    if ( ($this->m_aConfig['FTP_USE_SSL'] == 'YES') ) {
    
        if ( function_exists('ftp_ssl_connect') ) {
            $this->m_oFtpConnection = ftp_ssl_connect( $sServerAddress, $iServerPort );
    
            if ( !$this->m_oFtpConnection ) {
                $this->writeLog( "Attempt to connect to ".$sServerAddress.":".$iServerPort." with SSL+FTP failed. Will fallback to normal FTP." );
            }
            else {
                $this->writeLog( "Attempt to connect to ".$sServerAddress.":".$iServerPort." with SSL+FTP Succeeded. Now logging in ..." );
            }
        }
        else {
            $this->writeLog( "This server doesn't support FTPS (FTP with SSL). Will fallback to normal FTP." );
        }
    }
    
    //Fallback
    if ( !$this->m_oFtpConnection ) {
        $this->m_oFtpConnection = ftp_connect( $sServerAddress, $iServerPort );
    }
    
    // login after a successful connection
    if ( $this->m_oFtpConnection ) {
        $fLoginResult = ftp_login( $this->m_oFtpConnection, $this->m_aConfig['FTP_USERNAME'], $this->m_aConfig['FTP_PASSWORD'] ); 
        //echo $fLoginResult;
    }
    else {
        $this->writeLog( "Attempt to connect to ".$sServerAddress.":".$iServerPort." failed." );
    }
    
    // check connection
    if ( (!$this->m_oFtpConnection) || (!$fLoginResult) ) { 
        $this->writeLog( "FTP connection has failed!" );
    } else {
        $this->writeLog( "FTP connection was successful with ".$sServerAddress.":".$iServerPort );
        $fSuccess = true;
    }
    
    // Set to Passive connection if login was successful and this setting was set.
    if ( $fSuccess && ($this->m_aConfig['FTP_USE_PASSIVE'] == 'YES') ) {
    
        if ( ftp_pasv( $this->m_oFtpConnection, true ) ) {
            $this->writeLog( "FTP connection was set to PASSIVE mode." );
        }
        else {
            $this->writeLog( "Attempted to set FTP connection to PASSIVE mode but failed. Going to continue with copy anyway. If the script fails, review this as a possible source." );
        }
    }
    

    The response is successful: (I have replaced my IP with xx values)

    Attempt to connect to xx.xx.xx.xx:21 with SSL+FTP Succeeded. Now logging in ...
    FTP connection was successful with xx.xx.xx.xx:21
    FTP connection was set to PASSIVE mode.

    But when the system hits this:

    $fSuccess = false;
    
    $sDestinationFile = $this->m_aConfig['FTP_PATH_TO_COPY'] . $insDbFileName;
    
    // upload the file
    $fUpload = ftp_put( $this->m_oFtpConnection, $sDestinationFile, $insDbFileName, FTP_BINARY ); 
    
    // check upload status
    if (!$fUpload) { 
        $this->writeLog( "FTP upload has failed! Check the log file for errors. Try changing PASSIVE and SSL options in the config." );
        return false;
    } else {
        $this->writeLog( "Uploaded $insDbFileName to ".$this->m_aConfig['FTP_SERVER_ADDRESS']." as $sDestinationFile" );
        $fSuccess = true;
    }
    
    return $fSuccess;
    

    The response is the error

    Warning: ftp_put(): php_connect_nonb() failed: Operation now in progress (115) in
    /home/xxxxxxx/public_html/lab/test/perform_mysql_bk.php on line 326

    I have read many pages saying this error is caused by the FTP server returning an internal IP address instead of a public, but I have tested with other programs and all runs ok, the FTP server is sending the public IP when the PASV command is executed.

    Any ideas?

    • Martin Prikryl
      Martin Prikryl
      Actually did you test any FTP client on the same machine that runs your PHP code?
    • Daniel P.
      Daniel P.
      I'm having difficulties with that, the server is on a reseller account and no much possibilities on testing different clients, I've just tested with curl and I can connect without encryption, so when I use TLS, the system disconnects just after sending PASV and receiving answer from the server "227 Entering passive mode (xxx.xxx.xxx.xxx.198.104)" curl error is 7, can't connect to host... Could be something related with TLS in the server bad configured?
  • Daniel P.
    Daniel P. almost 7 years
    Thank you Martin, one last question, the firewall that my router has is blocking or the one that my PHP server has? or maybe the local computer that is running the FTP server is... What do you think?
  • Martin Prikryl
    Martin Prikryl almost 7 years
    You never mentioned any "router". But if you mean your local router, that's probably not involved, right? It can be both firewall of the PHP server as well as FTP server. You can test this by trying encrypted connection from your local machine.
  • Daniel P.
    Daniel P. almost 7 years
    Martin, I can connect successfully encrypted ftpes with my local machine running the FTP server, to the server running PHP and FTP server also...
  • Martin Prikryl
    Martin Prikryl almost 7 years
    "connect" is not enough a the test - can you retrieve a directory listing and upload a file?
  • Daniel P.
    Daniel P. almost 7 years
    I'm sorry, I can connect, retrieve directory listing, upload and download. I'm thinking there is something wrong on my end, I have an ISP modem/router in bridge mode, a router, and the local machine running FTP server.
  • Martin Prikryl
    Martin Prikryl almost 7 years
    OK, I see, you are connecting back to a local FTP server, right? So did you allow data connection ports in your local firewall and forwarded them on your router? - See also the link in my answer. - Anyway, that's not a programming question anymore.
  • Daniel P.
    Daniel P. almost 7 years
    Yes local firewall and ports forwarded, remember I can connect with the same credentials from a plesk server in other location, using encryption in passive mode. I'll still searching for the answer. Thank you for your help Martin!
  • Martin Prikryl
    Martin Prikryl almost 7 years
    OK, so that in can be a firewall of your PHP server. In any case, this is no longer a programming question. From a programming perspective, this question is answered.
  • humbads
    humbads almost 4 years
    I added the FTPS server's IP to WHM ConfigServer Security and Firewall Quick Allow IP address list, and then it worked. So it was definitely due to a firewall issue, since I already had ftp_set_option and ftp_pasv in place.
  • ShaneOH
    ShaneOH over 3 years
    This fixed the issue for me too. To add some context to this answer: elitehosts.com/blog/…
  • Đọc truyện hay
    Đọc truyện hay almost 3 years
    Thank you $connection = ftp_connect(self::FTP_SERVER) or die("Could not connect");; ftp_login($connection, self::FTP_USERNAME, self::FTP_PASSWORD); ftp_set_option($connection, FTP_USEPASVADDRESS, false); ftp_pasv($connection, true) or die("Cannot switch to passive mode");