Got a script that was working fine until recently. It's failing now in the following function, with the "sftp connect failed" error message. Any thoughts on things I should look at as possible causes? (I'm not particularly smart about SSH/SFTP -- I mostly just re-used code I found elsewhere.)

/**
 * Get sftp connection using SSH2
 * @return resource
 * @param  Array $sftpParams
 */
function sftpConnect(array $sftpParams)
{
	$connection = ssh2_connect($sftpParams['server'], $sftpParams['port']);
	if ($connection == false) {
		die('ssh2 connect failed'.PHP_EOL);
	}
	ssh2_auth_password($connection, $sftpParams['user'], $sftpParams['password']) or
		die('password auth failed'.PHP_EOL);
	$sftp = ssh2_sftp($connection);
	if($sftp == false) {
		die('sftp connect failed'.PHP_EOL);  // <------ right here
	}
	return $sftp;
}

    PS: Could it be a SSL cert issue? (I think we may have installed a new cert on that server around the time it started to fail.)

      Yes, definitely could be. Once an SSH or SFTP connection is made, the server's key fingerprint is stored in the "known_hosts" file (on the client machine); any changes to the remote server's key would cause the fingerprint to change and SSH would suspect a M.I.M. attack and fail to connect. I'd look into it by trying to SSH the box using the same credentials and environment your script is using. If you see a warning, that would explain it. In that case you would want to remove that fingerprint from "known_hosts", SSH the box manually again to verify the new fingerprint, and then try your script again.

        Yeah, seems like it must be something along those lines. Weird thing is I can connect via Filezilla on my PC using the same credentials, but not from our web server where the live script runs (e.g. sftp from the command line). I'm going to try to dump it on one of our networking guys to see if he can figure it out. 🙂

          17 days later

          This might be a firewall issue or it might be a cert issue. You might consider specifying callback functions in ssh2_connect to try and trap some errors?

          Alternatively, you might want to log in to the server where you are running this script and try connecting via ssh to the host manually from the command line. You may get some indication of what is failing. Or, if the connection attempt times out then maybe the remote host never gets your connection attempt because it's behind a firewall or something. If this was working before, it might have something to do with one of the machines moving to a new IP address.

            dalecosp;11038645 wrote:

            Yes, definitely could be. Once an SSH or SFTP connection is made, the server's key fingerprint is stored in the "known_hosts" file (on the client machine); any changes to the remote server's key would cause the fingerprint to change and SSH would suspect a M.I.M. attack and fail to connect.

            But this is only when using the shell isn't it? To implement the same thing in the script, you'd need to store the fingerprint and subsequently compare it against a call to [man]ssh2_fingerprint[/man]

              johanafm;11039259 wrote:

              But this is only when using the shell isn't it? To implement the same thing in the script, you'd need to store the fingerprint and subsequently compare it against a call to [man]ssh2_fingerprint[/man]

              Hmm, good point! So if the script is not connecting, we need to look a little earlier in the operation...?

              Truth be told, if this were me, first thing I'd do is check that the port was open using something like tcping...

                dalecosp;11039261 wrote:

                Hmm, good point! So if the script is not connecting, we need to look a little earlier in the operation...?

                Truth be told, if this were me, first thing I'd do is check that the port was open using something like tcping...

                Firewall could be excluding the server trying to connect but not one's workstation so it's important to check such a thing from the machine that'll ultimately be running the script.

                  Haven't really had a chance to dive into this again, but note that the ssh2_connect() and ssh2_auth_password() appear to work fine; but it's the ssh2_sftp() call that is failing. I tried adding a debug callback on the ssh2_connect(), but it did not output anything, while I still got the sftp connect failed message. 🙁

                  Here's what I tried:

                  function sftpConnect(array $sftpParams)
                  {
                  	$callbacks = array(
                  		'ignore'     => 'ignore',
                  		'debug'      => 'debug',
                  		'macerror'   => 'macerror',
                  		'disconnect' => 'disconnect'
                  	);
                  	$connection = ssh2_connect($sftpParams['server'], $sftpParams['port'], null, $callbacks);
                  	if ($connection == false) {
                  		die('ssh2 connect failed'.PHP_EOL);
                  	}
                  	ssh2_auth_password($connection, $sftpParams['user'], $sftpParams['password']) or
                  		die('password auth failed'.PHP_EOL);
                  	$sftp = ssh2_sftp($connection);
                  	if($sftp == false) {
                  		die('sftp connect failed'.PHP_EOL);
                  	}
                  	return $sftp;
                  }
                  
                  function ignore($msg)
                  {
                  	errout('IGNORE', $msg);
                  }
                  
                  function debug($msg, $lang, $display)
                  {
                  	errout('DEBUG', $msg);
                  }
                  
                  function macerror($packet)
                  {
                  	errout('MACERROR', print_r($packet,1));
                  }
                  
                  function disconnect($reason, $message, $language)
                  {
                  	errout("DISCONNECT", "Reason: '$reason', Message: '$message'");
                  }
                  
                  function errout($type, $msg)
                  {
                  	echo '['.date('Y-m-d H:i:s').'] -- '.$msg.PHP_EOL;
                  }
                  

                    Have you tried logging into the server yourself via SSH and then trying to connect to the destination server from there? It might give you a much better idea what is going on.

                      Could it simply be that our FTP count is disabled for some reason?

                      $ sftp nogdog@foo.bar.com:1022
                      Connecting to foo.bar.com...
                      nogdog@foo.bar.com's password:
                      Permission denied, please try again.
                      nogdog@foo.bar.com's password:
                      Permission denied, please try again.
                      nogdog@foo.bar.com's password:
                      Permission denied (password,keyboard-interactive).
                      Couldn't read packet: Connection reset by peer
                      $

                        Except that I can still connect via FileZilla using the same domain, user, and password on my work PC. :bemused:

                          I know there is some confusion about what SFTP is (ftp-over-ssh vs. some other kind of secure ftp protocol) but the way I've always used it and the way i expect it is used by ssh2_ functions is that you connect via ssh so you'll need a nix account on the remote machine rather than some separately maintained FTP account.

                          Try:

                          ssh nogdog@foo.bar.com:1022
                          

                          Or whatever port you need. Note that ssh connections usually happen over port 22.

                          The fact that you are getting prompted for a password means that a) you are apparnetly not blocked from connecting to the host/port you are contacting and b) there is some kind of login/ssh/sftp daemon running over there to accept/reject your login.

                          If the bouncer on the server is rejecting your login attempts, a few things occur to me:
                          1) maybe DNS issue? Try pinging the host from your workstation and your server too and see if the remote host comes back with the same IP address. If it's different, you'll need to maybe wipe a dns cache somewhere
                          2) network routing issue? Just because the IP address is identical doesn't mean you are connecting to the same machine 192.168.1.1 is my router over here, it's probably something different for you. Maybe your router...or something else.

                          In these cases, your server might be connecting to a different machine than your workstation does and that remote machine, although it is accepting connections, doesn't know who you are.

                          3) SSH/SFTP config problem? I am having a hard time picturing what could make the machine accept connections from filezilla but reject them from your server.

                          and of course there's always
                          4) User error. 😃. You sure you typed the passwords correctly?

                          Were it me, I would try to login to the finicky machine and watch what happens in the log files when you try to connect.

                            Even better, try "verbose" from the shell you had here:

                            $ sftp nogdog@foo.bar.com:1022
                            Connecting to foo.bar.com...
                            nogdog@foo.bar.com's password:
                            Permission denied, please try again.
                            nogdog@foo.bar.com's password:
                            Permission denied, please try again.
                            nogdog@foo.bar.com's password:
                            Permission denied (password,keyboard-interactive).
                            Couldn't read packet: Connection reset by peer
                            $
                            sftp -vvv nogdog@foo.bar.com:1022

                            should get you something meaningful.

                              I expect it would present a security risk for the server to give up too much information about why it denied permission so I'm thinking this is looking like either a user error (wrong password or something) or it's a server configuration issue. The one other possibility that occurred to me is that FileZilla might be using some other "secure ftp" protocol that is different than ssh2_sftp -- but I seem recall that this used to work and then something broke it so that last explanation seems unlikely.

                                "Verbose" may be an understatement, but hopefully useful?

                                $ sftp -vvv nogdog@foo.bar.com:1022
                                Connecting to foo.bar.com...
                                OpenSSH_5.3p1, OpenSSL 1.0.0-fips 29 Mar 2010
                                debug1: Reading configuration data /etc/ssh/ssh_config
                                debug1: Applying options for *
                                debug2: ssh_connect: needpriv 0
                                debug1: Connecting to foo.bar.com [208.21.37.8] port 22.
                                debug1: Connection established.
                                debug3: Not a RSA1 key file /home/fubar/.ssh/id_rsa.
                                debug2: key_type_from_name: unknown key type '-----BEGIN'
                                debug3: key_read: missing keytype
                                debug3: key_read: missing whitespace
                                debug3: key_read: missing whitespace
                                debug3: key_read: missing whitespace
                                debug3: key_read: missing whitespace
                                debug3: key_read: missing whitespace
                                debug3: key_read: missing whitespace
                                debug3: key_read: missing whitespace
                                debug3: key_read: missing whitespace
                                debug3: key_read: missing whitespace
                                debug3: key_read: missing whitespace
                                debug3: key_read: missing whitespace
                                debug3: key_read: missing whitespace
                                debug3: key_read: missing whitespace
                                debug3: key_read: missing whitespace
                                debug3: key_read: missing whitespace
                                debug3: key_read: missing whitespace
                                debug3: key_read: missing whitespace
                                debug3: key_read: missing whitespace
                                debug3: key_read: missing whitespace
                                debug3: key_read: missing whitespace
                                debug3: key_read: missing whitespace
                                debug3: key_read: missing whitespace
                                debug3: key_read: missing whitespace
                                debug3: key_read: missing whitespace
                                debug3: key_read: missing whitespace
                                debug2: key_type_from_name: unknown key type '-----END'
                                debug3: key_read: missing keytype
                                debug1: identity file /home/fubar/.ssh/id_rsa type 1
                                debug1: identity file /home/fubar/.ssh/id_dsa type -1
                                debug1: Remote protocol version 2.0, remote software version 3.2.3 F-Secure SSH Windows NT Server
                                debug1: no match: 3.2.3 F-Secure SSH Windows NT Server
                                debug1: Enabling compatibility mode for protocol 2.0
                                debug1: Local version string SSH-2.0-OpenSSH_5.3
                                debug2: fd 3 setting O_NONBLOCK
                                debug1: SSH2_MSG_KEXINIT sent
                                debug3: Wrote 792 bytes for a total of 813
                                debug3: Received SSH2_MSG_IGNORE
                                debug1: SSH2_MSG_KEXINIT received
                                debug2: kex_parse_kexinit: diffie-hellman-group-exchange-sha256,diffie-hellman-group-exchange-sha1,diffie-hellman-group14-sha1,diffie-hellman-group1-sha1
                                debug2: kex_parse_kexinit: ssh-rsa,ssh-dss
                                debug2: kex_parse_kexinit: aes128-ctr,aes192-ctr,aes256-ctr,arcfour256,arcfour128,aes128-cbc,3des-cbc,blowfish-cbc,cast128-cbc,aes192-cbc,aes256-cbc,arcfour,rijndael-cbc@lysator.liu.se
                                debug2: kex_parse_kexinit: aes128-ctr,aes192-ctr,aes256-ctr,arcfour256,arcfour128,aes128-cbc,3des-cbc,blowfish-cbc,cast128-cbc,aes192-cbc,aes256-cbc,arcfour,rijndael-cbc@lysator.liu.se
                                debug2: kex_parse_kexinit: hmac-md5,hmac-sha1,umac-64@openssh.com,hmac-ripemd160,hmac-ripemd160@openssh.com,hmac-sha1-96,hmac-md5-96
                                debug2: kex_parse_kexinit: hmac-md5,hmac-sha1,umac-64@openssh.com,hmac-ripemd160,hmac-ripemd160@openssh.com,hmac-sha1-96,hmac-md5-96
                                debug2: kex_parse_kexinit: none,zlib@openssh.com,zlib
                                debug2: kex_parse_kexinit: none,zlib@openssh.com,zlib
                                debug2: kex_parse_kexinit:
                                debug2: kex_parse_kexinit:
                                debug2: kex_parse_kexinit: first_kex_follows 0
                                debug2: kex_parse_kexinit: reserved 0
                                debug2: kex_parse_kexinit: diffie-hellman-group1-sha1
                                debug2: kex_parse_kexinit: ssh-rsa
                                debug2: kex_parse_kexinit: aes128-cbc
                                debug2: kex_parse_kexinit: aes128-cbc
                                debug2: kex_parse_kexinit: hmac-sha1,hmac-md5
                                debug2: kex_parse_kexinit: hmac-sha1,hmac-md5
                                debug2: kex_parse_kexinit: none,zlib
                                debug2: kex_parse_kexinit: none,zlib
                                debug2: kex_parse_kexinit:
                                debug2: kex_parse_kexinit:
                                debug2: kex_parse_kexinit: first_kex_follows 0
                                debug2: kex_parse_kexinit: reserved 0
                                debug2: mac_setup: found hmac-md5
                                debug1: kex: server->client aes128-cbc hmac-md5 none
                                debug2: mac_setup: found hmac-md5
                                debug1: kex: client->server aes128-cbc hmac-md5 none
                                debug2: dh_gen_key: priv key bits set: 131/256
                                debug2: bits set: 521/1024
                                debug1: sending SSH2_MSG_KEXDH_INIT
                                debug1: expecting SSH2_MSG_KEXDH_REPLY
                                debug3: Wrote 144 bytes for a total of 957
                                debug3: Received SSH2_MSG_IGNORE
                                debug3: check_host_in_hostfile: filename /home/fubar/.ssh/known_hosts
                                debug3: check_host_in_hostfile: match line 8
                                debug3: check_host_in_hostfile: filename /home/fubar/.ssh/known_hosts
                                debug3: check_host_in_hostfile: match line 9
                                debug1: Host 'foo.bar.com' is known and matches the RSA host key.
                                debug1: Found key in /home/fubar/.ssh/known_hosts:8
                                debug2: bits set: 506/1024
                                debug1: ssh_rsa_verify: signature correct
                                debug2: kex_derive_keys
                                debug2: set_newkeys: mode 1
                                debug1: SSH2_MSG_NEWKEYS sent
                                debug1: expecting SSH2_MSG_NEWKEYS
                                debug3: Wrote 16 bytes for a total of 973
                                debug3: Received SSH2_MSG_IGNORE
                                debug2: set_newkeys: mode 0
                                debug1: SSH2_MSG_NEWKEYS received
                                debug1: SSH2_MSG_SERVICE_REQUEST sent
                                debug3: Wrote 48 bytes for a total of 1021
                                debug3: Received SSH2_MSG_IGNORE
                                debug2: service_accept: ssh-userauth
                                debug1: SSH2_MSG_SERVICE_ACCEPT received
                                debug2: key: /home/fubar/.ssh/id_rsa (0x7fde5e390fb0)
                                debug2: key: /home/fubar/.ssh/id_dsa ((nil))
                                debug3: Wrote 64 bytes for a total of 1085
                                debug3: Received SSH2_MSG_IGNORE
                                debug1: Authentications that can continue: publickey,password,keyboard-interactive
                                debug3: start over, passed a different list publickey,password,keyboard-interactive
                                debug3: preferred gssapi-keyex,gssapi-with-mic,publickey,keyboard-interactive,password
                                debug3: authmethod_lookup publickey
                                debug3: remaining preferred: keyboard-interactive,password
                                debug3: authmethod_is_enabled publickey
                                debug1: Next authentication method: publickey
                                debug1: Offering public key: /home/fubar/.ssh/id_rsa
                                debug3: send_pubkey_test
                                debug2: we sent a publickey packet, wait for reply
                                debug3: Wrote 368 bytes for a total of 1453
                                debug3: Received SSH2_MSG_IGNORE
                                debug1: Authentications that can continue: password,keyboard-interactive
                                debug3: start over, passed a different list password,keyboard-interactive
                                debug3: preferred gssapi-keyex,gssapi-with-mic,publickey,keyboard-interactive,password
                                debug3: authmethod_lookup keyboard-interactive
                                debug3: remaining preferred: password
                                debug3: authmethod_is_enabled keyboard-interactive
                                debug1: Next authentication method: keyboard-interactive
                                debug2: userauth_kbdint
                                debug2: we sent a keyboard-interactive packet, wait for reply
                                debug3: Wrote 96 bytes for a total of 1549
                                debug3: Received SSH2_MSG_IGNORE
                                debug1: Authentications that can continue: password,keyboard-interactive
                                debug3: userauth_kbdint: disable: no info_req_seen
                                debug2: we did not send a packet, disable method
                                debug3: authmethod_lookup password
                                debug3: remaining preferred:
                                debug3: authmethod_is_enabled password
                                debug1: Next authentication method: password
                                nogdog@foo.bar.com's password:
                                debug3: packet_send2: adding 64 (len 58 padlen 6 extra_pad 64)
                                debug2: we sent a password packet, wait for reply
                                debug3: Wrote 144 bytes for a total of 1693
                                debug3: Received SSH2_MSG_IGNORE
                                debug1: Authentications that can continue: password,keyboard-interactive
                                Permission denied, please try again.
                                nogdog@foo.bar.com's password:
                                ^C
                                $

                                  And thanks so much for looking at this stuff!

                                    Not a big problem; everyone's in Vegas at a trade show except me, the part-time stats guy an an editorial assistant ;-)

                                    What does this command yield?

                                    file /home/fubar/.ssh/id_rsa

                                    It should say something like:

                                    file id_rsa
                                    id_rsa: PEM RSA private key

                                    And "file /home/fubar/.ssh/id_rsa.pub" should say:

                                    id_rsa.pub: OpenSSH RSA public key

                                    Given that this has only recently started failing (see the OP ... which I've apparently forgotten about, (Sorry!)) ... I'm guessing we're looking for changes on the server. What have they upgraded there recently? Do you have an old copy of /etc/ssh/sshd_config you can compare with the current version? (Or is this not a box you "own" to that degree?)

                                      $ file /home/fubar/.ssh/id_rsa
                                      /home/fubar/.ssh/id_rsa: ASCII text
                                      
                                      $ file /home/fubar/.ssh/id_rsa.pub
                                      /home/fubar/.ssh/id_rsa.pub: ASCII text, with very long lines
                                      

                                      If I actually cat those two files, the first looks like:

                                      -----BEGIN RSA PRIVATE KEY-----
                                      <a couple dozen lines of base-64 text>
                                      -----END RSA PRIVATE KEY-----
                                      

                                      And the second one:

                                      ssh-rsa AAAAB3N<...a bunch more base-64 stuff...>fcZGUIMiQ== fubar@hostname_i_am_on.domain.com
                                      

                                        Well, shucks. Linux's file(1) is a tad dumber than BSD's. apparently. From what you quote, the keys look right. That doesn't explain this to me:

                                        key_type_from_name: unknown key type '-----END'
                                        debug3: key_read: missing keytype

                                        What about the server config? Do you control that?