2013-04-17 1 views
1

Мне нужно подключиться к базе данных mysql на другом сервере, у меня есть ключ RSA для подключения к серверу, и у меня также есть все учетные данные, необходимые для подключения к базы данных, и используя эти следующие коды, я могу подключиться прекрасноcakePHP 2.x подключение к удаленной базе данных с использованием ключа

try { 
    $this->db = new PDO("mysql:host=$this->host;port=$this->port;dbname=$this->dbname", $this->sqlUser, $this->sqlPass); 
} catch (Exception $e) { 
    shell_exec("ssh -i /path/to/rsa/key/the_key [email protected] -L3307:localhost:3306 -N"); 
}; 

try { 
    $this->db = new PDO("mysql:host=$this->host;port=$this->port;dbname=$this->dbname", $this->sqlUser, $this->sqlPass); 
} catch (Exception $e) { 
    die($e->getMessage() . " (line:" . __LINE__ . ")"); 
}; 

однако, я строй приложения с помощью CakePHP 2.x, как я могу подключиться к этому удаленному серверу и базе данных с использованием конфигурации CakePHP-?

Благодаря

ответ

1

Хорошо я успел сделать это путем создания расширенного класса под названием FarAwayMysql.php под приложение/модели/DataSource/База данных

App::uses('DboSource', 'Model/Datasource'); 

class FarAwayMysql extends DboSource { 
public $description = "Faraway MySQL DBO Driver"; 

protected $_baseConfig = array(
    'persistent' => true, 
    'host' => 'localhost', 
    'login' => 'root', 
    'password' => '', 
    'database' => 'cake', 
    'port' => '3306', 
    'rsa' => '', 
    'remote_username' => '', 
    'remote_ip' => '' 
); 
protected $_connection = null; 

protected $_useAlias = true; 

public function connect() { 
    $config = $this->config; 
    $this->connected = false; 
    try { 
     $flags = array(
      PDO::ATTR_PERSISTENT => $config['persistent'], 
      PDO::MYSQL_ATTR_USE_BUFFERED_QUERY => true, 
      PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION 
     ); 
     if (!empty($config['encoding'])) { 
      $flags[PDO::MYSQL_ATTR_INIT_COMMAND] = 'SET NAMES ' . $config['encoding']; 
     } 
     if (empty($config['unix_socket'])) { 
      $dsn = "mysql:host={$config['host']};port={$config['port']};dbname={$config['database']}"; 
     } else { 
      $dsn = "mysql:unix_socket={$config['unix_socket']};dbname={$config['database']}"; 
     } 
     $this->_connection = new PDO(
      $dsn, 
      $config['login'], 
      $config['password'], 
      $flags 
     ); 
     $this->connected = true; 
    } catch (PDOException $e) { 
     echo "ssh -i {$config['rsa']} {$config['remote_username']}@{$config['remote_ip']} -L3307:{$config['host']}:3306 -N"; 
     shell_exec("ssh -i {$config['rsa']} {$config['remote_username']}@{$config['remote_ip']} -L3307:{$config['host']}:3306 -N"); 
    } 


    try { 
     $flags = array(
      PDO::ATTR_PERSISTENT => $config['persistent'], 
      PDO::MYSQL_ATTR_USE_BUFFERED_QUERY => true, 
      PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION 
     ); 
     if (!empty($config['encoding'])) { 
      $flags[PDO::MYSQL_ATTR_INIT_COMMAND] = 'SET NAMES ' . $config['encoding']; 
     } 
     if (empty($config['unix_socket'])) { 
      $dsn = "mysql:host={$config['host']};port={$config['port']};dbname={$config['database']}"; 
     } else { 
      $dsn = "mysql:unix_socket={$config['unix_socket']};dbname={$config['database']}"; 
     } 
     $this->_connection = new PDO(
      $dsn, 
      $config['login'], 
      $config['password'], 
      $flags 
     ); 
     $this->connected = true; 
    } catch (PDOException $e) {    
     throw new MissingConnectionException(array(
      'class' => get_class($this), 
      'message' => $e->getMessage() 
     )); 
    } 

    $this->_useAlias = (bool)version_compare($this->getVersion(), "4.1", ">="); 

    return $this->connected; 
} 
} 

добавлением 3 новых конфигов

protected $_baseConfig = array(
    'persistent' => true, 
    'host' => 'localhost', 
    'login' => 'root', 
    'password' => '', 
    'database' => 'cake', 
    'port' => '3306', 
    'rsa' => '', 
    'remote_username' => '', 
    'remote_ip' => '' 
); 

, а затем в вашем приложении/Config/database.php, это будет

public $faraway = array(
    'datasource' => 'Database/FarAwayMysql', 
    'persistent' => false, 
    'host' => 'localhost', 
    'login' => 'faraway_username', 
    'password' => 'faraway_password', 
    'database' => 'faraway_db_name', 
    'port' => '', 
    'rsa' => 'path/to/rsa/key', 
    'remote_username' => 'your_username', 
    'remote_ip' => 'your.ip.address' 
); 
0

спасибо за сообщение. Я использую PostgreSQL вместо MySQL, поэтому внес некоторые корректировки. Некоторые из них могут иметь отношение к MySQL.

1) когда shell_exec'ing, перенаправить вывод на /dev/null и запустить в фоновом режиме. Также порты изменились с 3306/3307 на 5432/5433

shell_exec("ssh -i {$config['rsa']} {$config['remote_username']}@{$config['remote_ip']} -L5433:{$config['host']}:5432 -N > /dev/null &") 

2) FarAwayPostgres.php следующего

<?php 
App::uses('Postgres', 'Model/Datasource/Database'); 

class FarAwayPostgres extends Postgres { 
     public $description = "Postgres over SSH"; 

     protected $_baseConfig = array(
       'persistent'   => true, 
       'host'     => 'localhost', 
       'login'     => 'root', 
       'password'    => '', 
       'database'    => 'cake', 
       'port'     => '5432', 
       'rsa'     => '', 
       'remote_username'  => '', 
       'remote_ip'    => '', 
       'sslmode'    => 'allow', 
       'schema'    => 'public', 
       'flags'     => array() 
     ); 

     protected $_connection = null; 
     protected $_useAlias = true; 

     public function connect() { 

       $config = $this->config; 
       $this->connected = false; 

       $flags = $config['flags'] + array(
         PDO::ATTR_PERSISTENT => $config['persistent'], 
         PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION 
       ); 

       try { 
         if (empty($config['unix_socket'])) { 
           $dsn = "pgsql:host={$config['host']};port={$config['port']};dbname={$config['database']};sslmode={$config['sslmode']}"; 
         } else { 
           $dsn = "pgsql:unix_socket={$config['unix_socket']};dbname={$config['database']}"; 
         } 

         $this->_connection = new PDO($dsn, $config['login'], $config['password'], $flags); 
         $this->connected = true; 
       } catch (PDOException $e) { 
         $cmd="ssh -i {$config['rsa']} {$config['remote_username']}@{$config['remote_ip']} -L5433:{$config['host']}:5432 -N > /dev/null &"; 
         shell_exec($cmd); 
         sleep(3); 
       } 


       try { 
         if (empty($config['unix_socket'])) { 
           $dsn = "pgsql:host={$config['host']};port={$config['port']};dbname={$config['database']};sslmode={$config['sslmode']}"; 
         } else { 
           $dsn = "pgsql:unix_socket={$config['unix_socket']};dbname={$config['database']}"; 
         } 

         $this->_connection = new PDO($dsn, $config['login'], $config['password'], $flags); 
         $this->connected = true; 
       } catch (PDOException $e) { 
         throw new MissingConnectionException(array(
           'class' => get_class($this), 
           'message' => $e->getMessage() 
         )); 
       } 

       return $this->connected; 
     } 
} 

Обратите внимание, как три второго сон был вставлен так, что попытка подключения к базе данных ожидает SSH, чтобы закончить.

Наконец, database.php:

<?php 
class DATABASE_CONFIG { 

     public $default = array(
       'datasource'  => 'Database/FarAwayPostgres', 
       'persistent'  => false, 
       'host'   => 'localhost', 
       'port'   => '5433', 
       'login'   => 'postgres', 
       'password'  => '', 
       'database'  => 'remote_db', 
       'rsa'    => '/var/www/.ssh/id_rsa', 
       'remote_username' => 'root', 
       'remote_ip'  => 'remote_server', 
       'prefix'   => '', 
       'encoding'  => 'utf8', 
     ); 

Закрытый ключ id_rsa сидит в домашней директории Apache и может быть прочитан Apache.

Теперь, наконец, перед использованием, выполните следующие действия:

su -m apache 
ssh -i /var/www/.ssh/id_rsa [email protected]_server 

для обновления known_hosts.