How to check if a connection is "sleeping" in php?

Asked

Viewed 287 times

1

I have the following script:

$fp = @fsockopen($IPAddress, $newport, $errno, $errstr, (float) 0.5);

if ($fp) {
    echo("Conectado\n");
} else {
    echo("Desconectado\n");
}

This script checks if a given port is open, works well.

I use this script for an SSH connection, then open a tunnel and can "talk" to the database on another server.

Tunnel stays active until I finish the corresponding SSH pid.

But even with the tunnel active, if a time passes I can no longer connect the database, I have to finish the tunnel and redo it, then I can access the base normally.

The detail is that the creation of the tunnel takes time because the networks that need to talk are slow, I would like to keep the tunnel active and be able to access the base by it.

The complete script below:

    <?php

// debug temporario
ini_set('display_errors', 1);
ini_set('display_startup_erros', 1);
error_reporting(E_ALL);

try {

    $host = 'IP_EXTERNO';
    $sshuser = 'user';
    $sshpass = 'senha';
    $dbuser = 'postgres';
    $dbpass = 'dbpass';
    $dbname = 'basename';
    $intranet = "IP_INTERNO";
    $newport = "NOVA_PORTA";
    $oldport = "PORTA_PADRAO";

    $IPAddress = "localhost";

    $fp = @fsockopen($IPAddress, $newport, $errno, $errstr, (float) 0.5);

    if ($fp) {
        echo("Conectado\n");
    } else {
        echo("Desconectado\n");
    }

    if (!$fp) {

        $command = "expect -c 'spawn ssh -f " . $sshuser . "@" . $host . " -L " . $newport . ":" . $intranet . ":" . $oldport . " -N; expect " . '"assword:"' . "; send " . '"' . $sshpass . '\r"' . "; expect send " . '"exit\r"' . "'";
        $res = shell_exec($command);
    } else {

        $res = true;

        fclose($fp);
    }

    if ($res) {
        $dbh = new PDO('pgsql:host=localhost;port=' . $newport . ';dbname=' . $dbname . '', $dbuser, $dbpass);

        // SQL Teste
        $sth = $dbh->prepare("select * from clientes codid desc limit 1");

        $sth->execute();

        $result = $sth->fetchAll();

        print_r($result);

        $dbh = null;

        function fProcessos($sshuser, $host) {

            $output = shell_exec('ps -x');
            $array = explode("\n", $output);

            for ($i = 1; $i < count($array); $i++) {
                $pos = strpos($array[$i], "ssh -f $sshuser@$host");
                if ($pos !== false) {
                    $id = substr($array[$i], 0, strpos($array[$i], ' ?'));
                    shell_exec('kill -9 ' . $id);
                }
            }
        }

        fProcessos($sshuser, $host);
    } else {
        echo("não passou\n");
    }
} catch (PDOException $e) {
    print "Error!: " . $e->getMessage() . "\n";
    die();
}

This script will run every 1/2h via cron, not via browser.

I’ve researched about persistent connection, but I didn’t see it as a solution since the script will run once and has no subprocesses.

1 answer

1

Actually this tunnel has nothing to do with PHP, PHP only runs the SSH daemon to create the tunnel, you must add some parameters to the command inside your shell_exec to keep the tunnel active.

Serveralivecountmax Sets the number of messages from the active server (see below) that can be sent without ssh receiving any message back from the server. If this limit is reached while the messages from the server being sent, ssh will be disconnected from the server, ending the session. It is important to note that the use of active server messages is very different from the Tcpkeepalive (below). Messages from the active server are sent through the encrypted channel and therefore cannot be falsified. The TCP keepalive option activated by Tcpkeepalive is spoofable. The mechanism the active server is valuable when the client or server depends on to know when a connection has become inactive.

The default value is 3. If, for example, Serveraliveinterval (see below) is set to 15 and Serveralivecountmax is left in the standard, if the server does not respond, ssh will be disconnected after approximately 45 seconds. This option applies to the version of protocol 2.

Serveraliveinterval Sets a timeout in seconds, after which, if no data has been received from the server, ssh (1) will send a message over the encrypted channel to request a server response. Default is 0, indicating that these messages will not be sent to the server. This option applies only to protocol version 2.

-N Does not execute a remote command. This is useful only for forwarding ports (protocol version only 2).

-T Disables pseudo-tty allocation.

-R [bind_address:]port:host:hostport Specifies that the port provided on the remote host (server) must be routed to the host and port provided on the local side. This works by assigning a socket to listen to the door on the remote side, and whenever a connection is made to this port, the connection is routed through the secure channel, and a connection is made to host the host port of the local machine.

Port forwards can also be specified in the configuration file. Privileged ports can only be routed when logging in as root on the remote machine. Ipv6 addresses can be specified by placing the address between brackets or using alternative syntax: [bind_address/]host/port/hostport.

By default, the listening socket on the server will only be linked to the loopback interface. This can be replaced by specifying a bind_address. An empty bind_address, or the '*' address, indicates that the remote socket should listen to all interfaces. Specifying a remote bind_address will only succeed if the Gatewayports server option is enabled (see sshd_config (5)).

If the port argument is '0', the listening port will be dynamically allocated to the server and reported to the client at runtime.

Example:

sshpass -p senha ssh -o ServerAliveInterval=10 -o ServerAliveCountMax=3 -N -T -R porta:127.0.0.1:22 user@host

There are other ways you can run commands on the remote machine, you can open the port on your server PGSQL and manage connections via user, where vc will perform better in your PHP code, because the function shell_exec Besides using too much machine feature, it is slow to execute shell commands.

Another simple and effective way is to create a block with the commands you want to run on the remote machine in a text file, copy this file with the scp and via ssh runs it on the remote machine.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.