Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

How to etablish an SSH2 tunnel with php ?

2,671 views
Skip to first unread message

Une Bévue

unread,
Mar 31, 2012, 12:40:09 PM3/31/12
to
The purpose is to query a remote PostgreSQL database via an ssh tunnel.

If i do the tunnel "by hand" from terminal using :
$ ssh -L 3333:localhost:5432 yt@iMac

then, i can query a remote database :
$host="localhost";
$port=3333;
$username='yt';
$password='topsecret';
$db = new PDO("pgsql:dbname=$dbname;host=$host;port=$port",
$username, $password );
$ret=$db->query('SELECT * FROM categories;');
if($ret){
while($row=$ret->fetch()){
print_r($row);
}
}else{
echo 'Error';
}

i've installes libssh2 for PHP on this computer, here is part of my
info.php :

SSH2 support enabled
extension version 0.11.2
libssh2 version 1.2.6
banner SSH-2.0-libssh2_1.2.6
remote forwarding enabled
hostbased auth enabled
polling support enabled
publickey subsystem enabled

however, even if i can "connect", authentification fail, either using
password or keys...

the code used :
function connect_to($machine)
{
$connection=@ssh2_connect($machine, 22, array("hostkey"=>"ssh-dsa"));
if(!$connection){
echo "No connection.<br />\n";
return false;
} else {
echo "Connection établie.<br />\n";
}

$fingerprint=@ssh2_fingerprint($connection, SSH2_FINGERPRINT_MD5 |
SSH2_FINGERPRINT_HEX);
echo "\$fingerprint = $fingerprint<br />\n";

/* Utilisation de public/private key */
if(@ssh2_auth_pubkey_file($connection, "yt",
'/home/yt/.ssh/id_dsa.pub', '/home/yt/.ssh/id_dsa',
'my -valid- passphrase')){
echo "Authentification réussie.<br />\n";
return array($connection,$fingerprint);
} else {
echo "Échec de l'authentification.<br />\n";
return false;
}
}

notice i get "Connection établie" and also the fingerprint.

if after the print out of fingerprint i try a command i get nothing
after an amout of time but without error :
$stdout_stream=@ssh2_exec($connection, 'ls -al');

Mr. B-o-B

unread,
Mar 31, 2012, 1:35:48 PM3/31/12
to
Une Bévue cried from the depths of the abyss...
I don't know the answer here, but I have several setups using remote db's
& I use stunnel (SSL) instead of SSH.

http://www.stunnel.org

Assuming you have static IP's on both sides it works well. End result is
the same.

Good Luck!

Mr. B-o-b

Jerry Stuckle

unread,
Mar 31, 2012, 3:18:42 PM3/31/12
to
Are you trying this after printing the fingerprint or after
authorization? Does the user have permission to issue commands on the
remote system (can you SSH into the system manually and execute an 'ls'
command?

And I suspect the reason you don't get an error is you have blocked all
error messages with the '@' operator. That's something you should
almost never use (if you're getting errors, fix the errors!).

Get rid of the '@'s, and in the php.ini file (on your development
system) ensure you have:

error_reporting = E_ALL
display_errors = on

See what you get.

--
==================
Remove the "x" from my email address
Jerry Stuckle
JDS Computer Training Corp.
jstu...@attglobal.net
==================

M. Strobel

unread,
Mar 31, 2012, 6:56:24 PM3/31/12
to
stunnel is a good solution when it is difficult to setup SSL/TLS directly in/for a
service.

This is not the case with Postgresql, you get remote access and ssl capability by
giving it a certificate, and putting your IP into pg_hba.conf. Very easy to configure
IMO. I use it a lot, and the good thing is the client libraries support it out of the
box.

So I would question the need to use a ssh tunnel.

/Str.

Une Bévue

unread,
Apr 1, 2012, 12:51:01 AM4/1/12
to
Le 31/03/2012 19:35, Mr. B-o-B a écrit :
> I don't know the answer here, but I have several setups using remote
> db's & I use stunnel (SSL) instead of SSH.
>
> http://www.stunnel.org
>
> Assuming you have static IP's on both sides it works well. End result
> is the same.
>

ok, thanks, I'll switch to that.

Une Bévue

unread,
Apr 1, 2012, 1:03:20 AM4/1/12
to
Le 31/03/2012 21:18, Jerry Stuckle a écrit :
> Are you trying this after printing the fingerprint

yes I've tested before authentification, knowing authentification fail...

> or after
> authorization? Does the user have permission to issue commands on the
> remote system (can you SSH into the system manually and execute an 'ls'
> command?

Yes, no prob, i can do, from terminal :
$ ssh yt@iMac 'ls -al'
for example and without entering a password or a passphrase because i do
an ssh-add when logging to the portable computer.

> And I suspect the reason you don't get an error is you have blocked all
> error messages with the '@' operator.

I did remove them, getting now :

Warning: ssh2_connect(): Failed overriding HOSTKEY method in
/home/yt/Sites/landp_public/ssh2.php on line 13
Connection établie.
$fingerprint = E7F46889FD0A2C02C7A5B1A083E05D92
Warning: ssh2_exec(): Unable to request a channel from remote host in
/home/yt/Sites/landp_public/ssh2.php on line 46
$res[0] =
Warning: ssh2_auth_pubkey_file(): Authentication failed for yt using
public key in /home/yt/Sites/landp_public/ssh2.php on line 32
Échec de l'authentification.
fail: unable to establish connection.
$con = .

Jerry Stuckle

unread,
Apr 1, 2012, 10:00:18 AM4/1/12
to
That helps a lot. A quick google of your first message finds your
hostkey method is wrong. Try "ssh-dss" and see if that doesn't work better.

Une Bévue

unread,
Apr 1, 2012, 10:42:47 AM4/1/12
to
Le 01/04/2012 16:00, Jerry Stuckle a écrit :
> That helps a lot. A quick google of your first message finds your
> hostkey method is wrong. Try "ssh-dss" and see if that doesn't work
> better.

fine thanks, right now i get :

Warning: ssh2_auth_pubkey_file(): Authentication failed for yt using
public key in /home/yt/Sites/landp_public/ssh2.php on line 46

however, the php script does :
if(ssh2_auth_pubkey_file($connection, "yt",
'/home/yt/.ssh/id_dsa.pub', '/home/yt/.ssh/id_dsa',
'Wo es war, soll Ich werden.')){
echo "Authentification réussie.<br />\n";

then, it is using the key from user 'yt' (ie. me) but, afaik, php is of
user 'www_data'.

then, perhaps, i do have to generate a key and a ~/.ssh/config for
www_data ?

using password authentification :
if(ssh2_auth_password($connection, "yt", "my_pwd")){
echo "Authentification réussie.<br />\n";

the error is :

Warning: ssh2_auth_password(): Authentication failed for yt using
password in /home/yt/Sites/landp_public/ssh2.php on line 49 Échec de
l'authentification.


Jerry Stuckle

unread,
Apr 1, 2012, 9:19:36 PM4/1/12
to
Does your www-data user have access to the key files? They need to be
readable by www-data (but you shouldn't have to create a new key for the
web user).

Une Bévue

unread,
Apr 2, 2012, 2:26:19 AM4/2/12
to
Le 02/04/2012 03:19, Jerry Stuckle a écrit :

>
> Does your www-data user have access to the key files? They need to be
> readable by www-data (but you shouldn't have to create a new key for the
> web user).
>

not for the time being :
.-(~)-------------------------------------(yt@D620)-
`--> lal .ssh
total 28
drwxr-xr-x 2 yt yt 4096 2012-01-03 17:06 .
drwxr-xr-x 91 yt yt 4096 2012-04-02 08:11 ..
-rw------- 1 yt yt 998 2012-02-04 09:32 authorized_keys
-rw------- 1 yt yt 137 2012-02-07 13:09 config
-rw------- 1 yt yt 751 2011-12-20 09:50 id_dsa
-rw-r--r-- 1 yt yt 597 2011-12-20 09:50 id_dsa.pub
-rw-r--r-- 1 yt yt 1548 2012-01-25 08:17 known_hosts
.-(~)--------------------------------------(yt@D620)-
`-->

afaik, i can't let them readable by all user because otherwise ssh won't
work (?).

I'll try to change that one for id_dsa from -rw------ to -rw-r---- or
even -rw-r--r--

with the latest, i got :
Warning: ssh2_auth_password(): Authentication failed for yt using
password in /home/yt/Sites/landp_public/ssh2.php on line 49

then, with passphrase :
Warning: ssh2_auth_pubkey_file(): Authentication failed for yt using
public key in /home/yt/Sites/landp_public/ssh2.php on line 46


same errors when all the files in my .ssh folder are readable for all
people.

even with those pems change on .ssh, I'm still able to connect directly by :
$ ssh yt@iMac

thanks for your answer.

Une Bévue

unread,
Apr 2, 2012, 6:01:56 AM4/2/12
to
Le 02/04/2012 08:26, Une Bévue a écrit :

>
> even with those pems change on .ssh, I'm still able to connect directly
> by :
> $ ssh yt@iMac

this was before i've restarted my portable computer, right now i got :

> `--> ssh yt@iMac
> @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
> @ WARNING: UNPROTECTED PRIVATE KEY FILE! @
> @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
> Permissions 0644 for '/home/yt/.ssh/id_dsa' are too open.
> It is recommended that your private key files are NOT accessible by others.
> This private key will be ignored.
> bad permissions: ignore key: /home/yt/.ssh/id_dsa
> Password:
> Last login: Mon Apr 2 08:24:58 2012 from dell-pal

then, i've to go back to preceeding perms...

M. Strobel

unread,
Apr 2, 2012, 6:31:28 AM4/2/12
to
Am 01.04.2012 07:03, schrieb Une Bévue:
> Le 31/03/2012 21:18, Jerry Stuckle a écrit :
>> Are you trying this after printing the fingerprint
>
> yes I've tested before authentification, knowing authentification fail...
>

You have tested login, but did you test the port forwarding?

/Str.

M. Strobel

unread,
Apr 2, 2012, 6:54:49 AM4/2/12
to
You said you did, in your first post.

Okay, so tunneling is working for your login.

Is your PHP script running in a web server? If yes, you have to setup and test for
the web server user id. The web server can still use your login on the remote system,
but it needs its own ssh files.

I would only try to do it in my LAN.

I would rather get SSL for Postgresql working (give it a self signed certificate),
and allow access for your IP.

/Str.

Une Bévue

unread,
Apr 2, 2012, 7:12:34 AM4/2/12
to
Le 02/04/2012 12:31, M. Strobel a écrit :
> You have tested login, but did you test the port forwarding?

port forwarding works like a charm, when i do, on terminal :

$ ssh -l 3333:localhost:5432 yt@iMac

i can, from php connect to the remote psql server as if it is on
localhost, i do have only to change the port.


Une Bévue

unread,
Apr 2, 2012, 7:14:10 AM4/2/12
to
Le 02/04/2012 12:54, M. Strobel a écrit :
> I would rather get SSL for Postgresql working (give it a self signed certificate),
> and allow access for your IP.

Yes, that's right, i plan to do that this afternoon.
I know -nothing- about SSL...

Peter H. Coffin

unread,
Apr 2, 2012, 8:15:02 AM4/2/12
to
On Mon, 02 Apr 2012 08:26:19 +0200, Une B?vue wrote:
> Le 02/04/2012 03:19, Jerry Stuckle a ?crit :
>
>>
>> Does your www-data user have access to the key files? They need to be
>> readable by www-data (but you shouldn't have to create a new key for the
>> web user).
>>
>
> not for the time being :
> .-(~)-------------------------------------(yt@D620)-
> `--> lal .ssh
> total 28
> drwxr-xr-x 2 yt yt 4096 2012-01-03 17:06 .
> drwxr-xr-x 91 yt yt 4096 2012-04-02 08:11 ..
> -rw------- 1 yt yt 998 2012-02-04 09:32 authorized_keys
> -rw------- 1 yt yt 137 2012-02-07 13:09 config
> -rw------- 1 yt yt 751 2011-12-20 09:50 id_dsa
> -rw-r--r-- 1 yt yt 597 2011-12-20 09:50 id_dsa.pub
> -rw-r--r-- 1 yt yt 1548 2012-01-25 08:17 known_hosts
> .-(~)--------------------------------------(yt@D620)-
> `-->
>
> afaik, i can't let them readable by all user because otherwise ssh won't
> work (?).

That is correct. HOWEVER, authorized_keys authorizes access for ANY
public half in its lists. Which means many private keys can exist for a
single login ID, and you can create a fresh pair, for www-data, where
www-data owns the private half exclusively (in some place that is not in
$DOCROOT, but also not your own .ssh directory) for its authentication
use, just like yt owns the above id_dsa exclusively.

--
For their next act, they'll no doubt be buying a firewall running under
NT, which makes about as much sense as building a prison out of
meringue.
-- Tanuki

Jerry Stuckle

unread,
Apr 2, 2012, 9:04:04 AM4/2/12
to
They have to be readable by the www-data user to be able to be used in
authentication. You don't, however, have to make them readable by all;
they can be owned by www-data, for instance. Or you should be able to
make copies of them (I don't like to do this) and have those copies
available to www-data (warning - do NOT place them in your web directory!).

Mr. B-o-B

unread,
Apr 2, 2012, 1:12:34 PM4/2/12
to
Une Bévue cried from the depths of the abyss...

Don't worry. There is a lot of info in the net about it. It's a lot
simpler, requires no extra coding (like shh does), and once it's setup you
will forget it is even there.


Mr. B-o-B
--
"I want to learn the ways of the Source, and be a Jedi like my Father"

Jason Playne

unread,
Apr 4, 2012, 4:36:46 AM4/4/12
to
> \n";
> return false;
> } else {
> echo "Connection établie.
> \n";
> }
>
> $fingerprint=@ssh2_fingerprint($connection, SSH2_FINGERPRINT_MD5 |
> SSH2_FINGERPRINT_HEX);
> echo "\$fingerprint = $fingerprint
> \n";
>
> /* Utilisation de public/private key */
> if(@ssh2_auth_pubkey_file($connection, "yt",
> '/home/yt/.ssh/id_dsa.pub', '/home/yt/.ssh/id_dsa',
> 'my -valid- passphrase')){
> echo "Authentification réussie.
> \n";
> return array($connection,$fingerprint);
> } else {
> echo "Échec de l'authentification.
> \n";
> return false;
> }
> }
>
> notice i get "Connection établie" and also the fingerprint.
>
> if after the print out of fingerprint i try a command i get nothing
> after an amout of time but without error :
> $stdout_stream=@ssh2_exec($connection, 'ls -al');



> \n";
> return false;
> } else {
> echo "Connection établie.
> \n";
> }
>
> $fingerprint=@ssh2_fingerprint($connection, SSH2_FINGERPRINT_MD5 |
> SSH2_FINGERPRINT_HEX);
> echo "\$fingerprint = $fingerprint
> \n";
>
> /* Utilisation de public/private key */
> if(@ssh2_auth_pubkey_file($connection, "yt",
> '/home/yt/.ssh/id_dsa.pub', '/home/yt/.ssh/id_dsa',
> 'my -valid- passphrase')){
> echo "Authentification réussie.
> \n";
> return array($connection,$fingerprint);
> } else {
> echo "Échec de l'authentification.
> \n";
> return false;
> }
> }
>
> notice i get "Connection établie" and also the fingerprint.
>
> if after the print out of fingerprint i try a command i get nothing
> after an amout of time but without error :
> $stdout_stream=@ssh2_exec($connection, 'ls -al');



> \n";
> return false;
> } else {
> echo "Connection établie.
> \n";
> }
>
> $fingerprint=@ssh2_fingerprint($connection, SSH2_FINGERPRINT_MD5 |
> SSH2_FINGERPRINT_HEX);
> echo "\$fingerprint = $fingerprint
> \n";
>
> /* Utilisation de public/private key */
> if(@ssh2_auth_pubkey_file($connection, "yt",
> '/home/yt/.ssh/id_dsa.pub', '/home/yt/.ssh/id_dsa',
> 'my -valid- passphrase')){
> echo "Authentification réussie.
> \n";
> return array($connection,$fingerprint);
> } else {
> echo "Échec de l'authentification.
> \n";
> return false;
> }
> }
>
> notice i get "Connection établie" and also the fingerprint.
>
> if after the print out of fingerprint i try a command i get nothing
> after an amout of time but without error :
> $stdout_stream=@ssh2_exec($connection, 'ls -al');

You can always generate a script to run on the remove server and run it over ssh.

e.g.
cat > /tmp/yarwoot1
#!/usr/bin/php
<?php

$sql = "select * from yar";
...


and then from your app

<?php

$out = shell_exec("ssh -iidentityfile user@host /tmp/yarwoot1");
// do something with $out here

Une Bévue

unread,
Apr 5, 2012, 1:36:08 AM4/5/12
to
Jason Playne <ja...@jasonplayne.com> wrote:

>
> You can always generate a script to run on the remove server and run it
over ssh.

Yes OK, good remark, thanks.

--
� Qui ne p�te ni ne rote est vou� � l'explosion. �
(Lao-Tseu)

Jerry Stuckle

unread,
Apr 5, 2012, 8:10:52 AM4/5/12
to
Maybe. Many hosts have disabled shell_exec(), or if it's enabled, the
web user has very little few privileges. Also, depending on what it
does, there could be security concerns when running from a web page (web
pages are typically less secure than an SSH tunnel).
0 new messages