I have a client requirement to secure our application connection with the Oracle Database. Currently, we are using OCI8 PHP library (oci_connect) to connect to Oracle using credentials which we have in a config file (a kind of plain text) where we maintain all our credentials.
Now they want to improve the security by implementing some kind secure connection using SSH so communication from application to DB will be secure. I read on the internet that this is possible.
My problem is that I don't know to achieve that with PHP OCI library even if our administrator implement SSH based authentication between the application server and DB server because OCI library uses username and password to connect with DB server.
I am trying to understand if there is any way we can achieve this type of auth connections from PHP to Oracle.
I am using Oracle 12c Enterprise edition.
To answer the second part - Establishing a secure connection using SSH. We can try using Oracle Wallets. So we don't need to save any plain text password in the app server.
Try connecting from PHP to an Oracle DB using an Oracle Wallet using below steps
1 - Create a wallet (https://docs.oracle.com/cd/B19306_01/network.102/b14266/cnctslsh.htm#g1033548)
2 - Put the Oracle instant client and the wallet files somewhere on the server with PHP (for example /opt/instantclient and /opt/wallet)
3 - Start Apache with the following variables:
ORACLE_HOME=/opt/instantclient
LD_LIBRARY_PATH=/opt/instantclient
TNS_ADMIN=/opt/wallet
4 - In /opt/wallet create a tnsnames.ora files with this content:
WALLET_NAME =
(DESCRIPTION =
(ADDRESS = (PROTOCOL = TCP)(HOST = DB_IP)(PORT = DB_PORT))
(CONNECT_DATA = (SID = DB_SID))
)
where WALLET_NAME it's the name of the wallet chosen when the wallet has been created, DB_IP it's the database ip address or hostname, DB_PORT it's the db port, and DB_SID it's the sid of the database
5 - In /opt/wallet create a sqlnet.ora files with this content:
WALLET_LOCATION =
(SOURCE =
(METHOD = FILE)
(METHOD_DATA =
(DIRECTORY = /opt/wallet)
)
)
SQLNET.WALLET_OVERRIDE = TRUE
6 - Restart Apache
On the PHP code side now you can connect to the database opening a connection with the following code:
$conn = oci_connect("/", "", "WALLET_NAME", null, OCI_CRED_EXT);
OCI_CRED_EXT This tells Oracle to use External or OS authentication, which must be configured in the database. The OCI_CRED_EXT flag can only be used with username of "/" and a empty password.
Related
So I have created a www site on my private server. It's basically a PHP + javascript page. Now I need to move it to BlueMix. The only problem is that while I used a MySQL db on my private server now I need to use SQL Database-s2 and all (both my php page and the db) on BlueMix.
Mike
You have to parse db information from VCAP_SERVICES\service credentials.
If your database service is "SQL Database" you can connect to SQLDB using this example code:
//parse VCAP_SERVICES Environment variable
$vcap_services = $_ENV["VCAP_SERVICES"];
$services_json = json_decode($vcap_services,true);
$sqldb = $services_json["sqldb"];
if (empty($sqldb)) {
echo "No sqldb service instance is bound. Please bind a sqldb service instance";
return;
}
//Get Credentials object (db,host,port,username,password)
$sqldb_config = $services_json["sqldb"][0]["credentials"];
$conn_string = "DRIVER={IBM DB2 ODBC DRIVER};DATABASE=".
$sqldb_config["db"].
";HOSTNAME=".
$sqldb_config["host"].
";PORT=".
$sqldb_config["port"].
";PROTOCOL=TCPIP;UID=".
$sqldb_config["username"].
";PWD=".
$sqldb_config["password"].
";";
$conn = db2_connect($conn_string, '', ''); //db connection
the information is automatically retrieved from the VCAP_SERVICES.
The application read the env. variable and retrieves automatically the username,host,db password field.
but you can manually set db, host, port, username, password looking at
service credentials of the service:
How to retrieve credentials information:
from DASHBOARD UI
click on your service icon in the dashboard UI
in the new page, in the left menu, click on "Service Credentials"
If you don't see any credentials but you see the button "ADD CREDENTIALS", click on this button, edit the name credentials as you want e click on "ADD" button.
In this way you will see the service information (credentials)
from CF command line
cf env your_app_name
In the code we are using DB2 module: use the following buildpack https://github.com/ibmdb/db2heroku-buildpack-php when you are using SQLDB with PHP. It will install the 'ibm_db2' php module for your use.
You can set the buildpack when you push your application on Bluemix:
cf push <your_app_name> -b https://github.com/ibmdb/db2heroku-buildpack-php
You can deploy your application on Bluemix using the PHP buildpack. After creating the SQL Database instance and binding it to the PHP application on Bluemix, to connect to the SQLDB service in Bluemix you can use db2_connect with the credentials retrieved from the VCAP_SERVICES environment variable. I don't know your business requirements, however if you want to keep consistency across the environments and don't want to migrate to another RDBMS you could try ClearDB, that is a reliable, fault tolerant, geo-distributed database-as-a-service for your MySQL powered applications.
I am install service MySQL to my PHP app on Bluemix and the error is on connection establish on this lines:
$con = mysql_connect("192.155.247.248:3307","uqDqUZ2EKoZ5I","pWXeBZbNtdpOv");
if (!$con){
echo "Failed to connect to MySQL: " .mysql_error();
}
mysql_select_db("d65a2b7e14b594d18a049ac918a4a8603",$con);
Quentin suggested to use mysqli instead of mysql_* as the latter is deprecated, i.e. try this:
$mysqli = new mysqli("192.155.247.248:3307","uqDqUZ2EKoZ5I","pWXeBZbNtdpOv", "MYDB");
$result = $mysqli->query("SELECT * from MYTABLE");
$row = $result->fetch_assoc();
Create a folder
.bp-config/options.json in the parent folder
and add
{
"PHP_EXTENSIONS": ["mysqli"]
}
in the options.json folder
the sqli connect will work fine now
Are you getting:
ERROR 2003 (HY000): Can't connect to MySQL server on '$host' (60).
A developer may have asked a similar question on developerWorks.
The answer seemed to be as follows:
Downloaded the latest PHPMyAdmin(4.1.9)
Created a BlueMix application using - cf push -b https://github.com/dmikusa-pivotal/cf-php-build-pack.git
${myPhpAdminApp} . Note: the PHP build pack is used is PHP 5.4.26, which enables multi-byte support (it is different from the Heroku one in the BlueMix docs). This was necessary because the Heroku pack bundled PHP 5.3.27 which
doesn't enable "multi-byte" character support by default. Multi-byte
support is required to be enabled by PHPMyAdmin apparently.
Added the existing MySQL service to this app. And picked the host, port, user, and password details from the VCAP_SERVICES
environment variable.
Copied config.sample.inc.php in the PHPMyAdmin to config.inc.php and added or modified the following lines in it based on the MySQL
service VCAP_SERVICES details picked in previous step -
$cfg['Servers'][$i]['host'] = 'host-ip-from-vcap_services';
$cfg['Servers'][$i]['port'] = 'port-from-vcap_services';
$cfg['Servers'][$i]['user'] = 'user-from-vcap_services';
$cfg['Servers'][$i]['password'] = 'password-from-vcap_services';
Pushed the updates using the above cf push ... again.
How do I upload my MySQL DB to Heroku for use with a PHP app? The only docs I found on Heroku are this:
Using ClearDB with PHP
Connecting to ClearDB from PHP is super easy, and merely requires the parsing of the CLEARDB_DATABASE_URL to get connected, like this:
<?php
$url=parse_url(getenv("CLEARDB_DATABASE_URL"));
$server = $url["host"];
$username = $url["user"];
$password = $url["pass"];
$db = substr($url["path"],1);
mysql_connect($server, $username, $password);
mysql_select_db($db);
?>
I don't understand how to fill the ClearDB with my data without an SSH connection, or how to create a database or how to connect to it?
From ClearDB's Developer Center FAQ:
For importing data into your MySQL database, we recommend that you use both the mysql command line client as well as the mysqldump database backup utility.
Assuming you have the connection information available, use the mysql and mysqldump utilities on your local machine to connect directly to ClearDB remotely and import the data. This other SO answer may help: How to copy a Database from one server to another server in PHP?
You can export a database dump with mysql_dump locally, and then given the username/password/host information from heroku config, you can use they mysql utility locally to import to the remote host, so something like this:
$ mysqldump --user=db1user --password=db1pass local_database > db.sql
$ mysql --host=remote_host --user=db2user --password=db2pass myschema < db.sql
I encountered a problem that I have spent hours fixing that. Here is the problem:
I am trying to connect to a remote Oracle 8i server using Oracle 11 instant client: here is my connection string in PHP:
$conn = oci_connect('db_user', 'db_pass', "db_ip/db_service");
db_ip is the ip of the server, such as "12.34.56.78".
db_service is the service of server, such as "test".
The error shown is
ORA-12514: TNS:listener does not currently know of service requested in connect descriptor
I could use the same client to connect to another Oracle 10g server. The php code is same, only change the db_user or db_pass or db_ip. db_service is not provided.
I don't use tnsnames.ora for either oracle 10g server or oracle 8i server. I just use the simple IP of server. Does this matter?
Server using: Windows Server 2008 R2
PHP: php 5.2.17
Oracle Instant Client: 11_2
Any ideas will be appreciated.
Updated
Php can also work now. My php folder is under Programfiles (x86), the parenthesis is not allowed. So I moved the whole folder to C:\php, and configure the IIS to change php version. Reference:http://stackoverflow.com/questions/9215983/php-cant-connect-but-sqlplus-can
Updated
Thanks so much for Justin's help. It works!!! I just changed the sid to scblive instead of SCBLIVE. Their database name is scblive. I am still using 10.2.0.1, using sqlplus, I can connect to both oracle 10g and oracle 8i. Thanks soooo much!!
This is the tns names that works for oracle 8i:
scblive =
(DESCRIPTION =
(ADDRESS = (PROTOCOL = TCP)(HOST = [oracle 8i ip])(PORT = 1521))
(CONNECT_DATA =
(SERVER = DEDICATED)
(SID = scblive)
)
)
Another problem found, in php code, it shows the same error for either oracle 10g or oracle 8i.
ORA-12154: TNS:could not resolve the connect identifier specified
I just used following connection string:
$conn = oci_connect('user_name', 'pass', 'scblive');
for oracle 10g, if I used same connection string as before, the error still shows:
$conn = oci_connect('user_name', 'pass', [oracle 10g ip]);
Any ideas?
Earilier Update:
Thanks for #Justin's help. have tried 10.2.0.5, 10.2.0.4 or 10.1.0.0, none of them could work. I saw the the matrix. it seems instant client 8.1.7 or instant client 9.0.1 could work for both oracle 10g and oracle 8i. Does anyone have a link for those files? Oracle could only provide 10.1.0.5 and later.
This is expected behavior. The 11.2 client is not certified to connect with any version of Oracle 8i. You would need to have at least an Oracle 9.2.0.4 database. If you want to connect with and 8.1.7 database, you would need an Oracle 10.2 or earlier client. The initial versions of the 10.2 client were not compatible with a Windows Server 2008 R2 system but it should be possible to install the 10.2.0.5 client patchset. If you want to connect to an Oracle database that is earlier than 8.1.7, you would need an earlier version of the Oracle client which would probably require installing an earlier version of Windows.
If you have Metalink access, Metalink 207303.1 is the Client/ Server Interoperability Matrix.
If you really have the 10.2.0.5 full client installed, your TNS alias needs to use a SID. Service names didn't exist back in 8.1.7. You probably want to copy a TNS alias from a machine that is able to connect to the 8.1.7 database. My guess is that you want
SCBLIVE =
(DESCRIPTION =
(ADDRESS = (PROTOCOL = TCP)(HOST = [ORACLE 8i IP])(PORT = 1521))
(CONNECT_DATA = (SERVER = DEDICATED)(SID = SCBLIVE))
)
If that doesn't work, at a command line, type tnsping scblive and copy and paste the results.
I copy my previous Oracle 9/8 client's ora.... folder and all relevant dll to a specific folder and put these two folders into path variable. At a time, I succeed to connecting with Oracle 8.1.7 using oci in php.
I have two servers setup on Amazon AWS. One server is running PHP and the other has MySQL. I can connect to the MySQL database through my terminal and MySQL Query Browser.
I am trying to get a connection between the PHP and MySQL servers.
Here is the PHP Code that I am using (works for "localhost" databases)
$dbbase = 'mydb';
$dbuser = 'myuser'; // Your MySQL username
$dbpass = 'mypassword'; // ...and password
$dbhost = 'localhost:3306'; // Internal IP for MYSQL Server
// connect to database
$dblink = mysql_connect($dbhost, $dbuser, $dbpass)
or die ("System Down");
mysql_select_db($dbbase, $dblink)
or die ("Database Down");
It is my understanding that I should be able to route this an internal AWS traffic, but at this point I will take anything that works and build from there.
Here is what I have done:
Added the ip of the PHP server to the Security Group for MySQL(3306) permissions
Tried to use the internal, external, and private IPs/DNSs of the MySQL Server as the $dbhost variable
Created myuser#% (wildcard) on thy MySQL server
Any ideas or tips would be much appreciated.
I had the same issue - turns out MySQL extension for PHP is NO longer included in PHP5!
"In PHP 5 (updated PHP 5.0.4), the following changes exist. Built in: DOM, LibXML, Iconv, SimpleXML, SPL and SQLite. And the following are no longer built in: MySQL and Overload."
Source: http://php.net/manual/en/install.windows.extensions.php
I've got this working.
I think the big trick was to add this rule to the Security Group:
Type: MySQL
Source: 10.0.0.0/8
My understanding is that 10.0.0.0/8 covers all internal amazon IPs. I think you could tighten this up, but it is possible for the internal IP of your servers to change, so that would need to be managed.
Then in my PHP script I used the Private DNS of my MySQL Server. It should look something like this: ip-10-10-100-100.ec2.internal:3306
In the end, I think that is everything that I did.