Encrypting MySQL Traffic In Scripts - php

I need to be able to encrypt the MySQL traffic from a web server to a database server. I know how to set MySQL to use SSL based on the server and client settings in my.cnf however, this needs to be done using mysql_connect() in PHP. This may be a 2 part question.
1) Does mysql_connect() use the MySQL client settings that are set in my.cnf?
If not...
I have read that you can use MYSQL_CLIENT_SSL however, where is the SSL data obtained from? Does using MYSQL_CLIENT_SSL in the mysql_connect function automagically encrypt the traffic?
Simply put, what is the best way to do this?
Thanks!

If you connect to MySQL using SSL, all your traffic between your SSL client and server will be encrypted.
MYSQL_CLIENT_SSL is obsolete. Using mysqli if you need to use SSL,
$db = mysqli_init();
$db->ssl_set(null, null,'cacert.pem',NULL,NULL);
$db->real_connect('host','user','pass','db');

As an alternate solution, you can also use SSH tunnels to accomplish compression and encryption.

MYSQL_CLIENT_SSL was removed from PHP and should not work.
You have a few options: the first is that if your web server is also your database server, you don't need encryption because the connection never leaves your box: it just uses localhost.
The second option is to use what Pablo suggested above and take advantage of SSH tunnels. An SSH tunnel essentially does the same thing as an SSL connection, except it takes one "extra step" to get it going.
This seems like a pretty decent tutorial to help get you started:
http://www.revsys.com/writings/quicktips/ssh-tunnel.html
Hope this helps!

According to http://www.php.net/manual/en/mysql.constants.php#mysql.client-flags MYSQL_CLIENT_SSL is still part of PHP 4 and 5. You need to set up the SSL connection beforehand though. You'll have to generate certificates and a bunch of other hassle (http://www.madirish.net/?article=244) but it will encrypt the traffic between your web server and your database host.
As mentioned above, if your web server is on the same host as the database server this encryption is unnecessary as the data travels over a local socket and isn't exposed to the network. The SSL encryption only encrypts traffic over the network.
I would warn against using an SSH tunnel because they have a tendency to die and you'll have to worry about maintaining the connection.

Related

Submit Form Data through Web Server to MySQL Server using Stunnel?

I have a form that users can fill out, and the data will be stored into a MySQL database using PHP. The connection to the Apache server is encrypted through HTTPS, and I would like to encrypt the connection to the MySQL database. Both Apache and MySQL are on the same server machine.
I digged around the Interweb and Stunnel seems to be what I need. OpenSSL and SSL are supported and activated on the server, since the we are given the option of using the standard port and a stunnel port to connect to the MySQL server. However, all the articles I found online deal with using Stunnel to connect a MySQL client to an external MySQL Server, but not how to use PHP to connect to a local MySQL server. Am I right to assume that just because the form is transmitted through https, it doesn't mean that the connection to the database is also encrypted?
The PHP code I use to connect to MySQL is like this:
$mysqli = new mysqli("ip","user", "password", "database", "standardport");
This works fine using the standardport. However, if I change it to a Stunnel Port, I get a connection time-out error. Clearly I'm missing something; any help and advice is appreciated! Thanks!
You've already stated that you use an HTTPS connection to encrypt traffic between the clients browser and your webserver, and that the webserver and MySQL instance are on the same machine.
Assmuning the HTTPS connection is secure, this should be all you need to protect your data over public networks, and using a secure tunnel for a connection that is only present on the local machine simply adds an unnecessary layer of complexity.
Consider the following examples.
The first is how the connection looks without a secure tunnel.
browser <--HTTPS--> [ webserver <--> mysql ]
So in this scenario, the the connection between the webserver and mysql is unencrypted. Someone who has access to the machine (depending on permissions) will be able to observe all traffic between the webserver and/or read the physical databases from disk themselves.
Now, with a secure tunnel
[ webserver <--> stunnel <--ENCRYPTED--> stunnel <--> mysql ]
I hope you can see that the connections between the webserver and one secure tunnel endpoint, and the connection between mysql and the other endpoint are both unencrypted. In this scenario, exactly the same as before, someone with access to the machine could potentially see all traffic and read the databases from disk.
No additional security has been achieved.
Lastly
[ webserver <--> stunnel ] <--ENCRYPTED--> [ stunnel <--> mysql ]
When you are using two separate servers, then the local traffic is still unencrypted, however stunnel secures the stream between the two machines. Someone with local access to the machines may still be able to observe traffic and read data, however someone observing network traffic between servers will not.
A solution?
All that said, if you really want to encrypt the traffic between PHP and MySQL, even on the same machine, a slightly better solution exists than using stunnel.
MySQL supports SSL natively, as does PHP when both are compiled with SSL support. (Your installations may already be configured this way, it's up to you to check them)
The MySQL manual details how to configure your MySQL server with SSL support and PHP provides the function mysqli_ssl_set
Using this combination, you can natively encrypt the connection between PHP and the mysql server.
[ webserver <--ENCRYPTYED --> mysql ]
However someone with access to the machine may still be able to read the unencrypted database from disk, and may be able to observe the memory of running processes.
You are quite right, the internet is a dangerous place, and proper security is essential. If your server itself and the data it contains are not secure, all is lost, no matter what precautions you take securing how the data enters and leaves it.

Securing remote mysql connection

I'm in the unfortunate position of having to sync a local microsoft access database with a remote mysql database.
I have written a php script which will sync the databases every 10 minutes. However I'm definitely concerned about security.
So far I have set up remote mysql with cpanel, this allows only my I.P address to make connections. I've also made sure the user I'm connecting with has limited permissions.
However, I'm aware that the data I'll be sending back and forth will be unencrypted. Is there anything I can do to make sure my data is encrypted? I'd also like to know whether my mysql username/password is currently encrypted the way I have it set up?
Lucas
You can use secure connection to MySQL:
MySQL side: http://dev.mysql.com/doc/refman/5.5/en/secure-connections.html
PHP side: http://php.net/manual/en/mysqli.real-connect.php (MYSQLI_CLIENT_SSL flag)
I have not worked with SSL connections to MySQL with PHP, but, I think it is not hard to find needed information on http://php.net, http://dev.mysql.com and http://google.com
Update
This may help: http://www.madirish.net/node/244, PHP to MySQL SSL Connections, http://www.php.net/manual/en/mysqli.ssl-set.php
You could use the PHP mcrypt functions to encrypt and decrypt the data.
A good example of this can be found right on SOF: Best way to use PHP to encrypt and decrypt?

php mysql_connect security

If a web server and a database server are on different hosts, is it possible for a hacker to do packet sniffing or use some other method to get the database username/password when you use mysql_connect in the PHP code?
Yes mysql_connect() can be sniffed. The password is "scrambled", but this will not stop an attacker. All quires are thrown over the wire in plain text and the authenticated session can be hijacked if you are sniffing TCP sequence id's.
You must use full transport layer encryption which is possible using the MYSQL_CLIENT_SSL flag if you are worried about this attack. If you are putting a mysql connection over the internet or otherwise untrusted network then this is a necessity. This is not necessary if you are connecting via localhost.
I think that a hacker can sniff the packets if he has some kind of access to the web server or db server, or at least to the LAN where one of these servers are and in this case you have bigger problems. But if the web server is on webhost.com, the db is on dbhost.com and the hacker tries to sniff from outside then he cannot do much.

Read ssl data from PHP socket_listen()

Lets say a listening socket is created in PHP, and it accepts a secure connection.
How do I know that it's encrypted and how do I decode it?
From the way your question is worded, you are a very long way from being to implement any sort of solution to the question as you've asked it. Implementing your own SSL server using PHP and off the shelf components will be virtually impossible even for a total PHP guru. I don't imagine that anyone who really understood the problem would try to solve it in this way - a far more pragmatic approach would be to set up the server to listen on two different ports (or use 2 seperate servers) use an SSL proxy (e.g. stunnel) which only accepts connections from localhost for the SSL traffic, and write your server(s) to talk non-SSL. You know its secure if the connection arrives from localhost and on the port that listens for the stunnel connection (or someone is running their own client/proxy on your server).
HTH
C.

Does anyone know a SSH/ SFTP/ FTP wrapper around pfsockopen()?

Does anyone know a SSH/ SFTP/ FTP wrapper class around pfsockopen();?? I'm still on my quest to keep persistent connections in PHP.
After a quick read, it looks like opening a socket deals with a different layer then what you are wanting. You want to connect via SSH or SFTP, which is the Application Layer using a method that makes connections via TTP/TLS/UDP, which is the transport layer.
So really what you want (I think) is to create an SSL or TLS connection using the pfsockopen() function, and then use that connection to pass data via the SSH/SFTP protocol.
According to the PHP site:
If you have compiled in OpenSSL
support, you may prefix the hostname
with either ssl:// or tls:// to use an
SSL or TLS client connection over
TCP/IP to connect to the remote host.
So my best guess is that you set your hostname to start with ssl:// and then use the SSH or SFTP port as the port (so port 22 or port 989). Something like:
$persistent_socket = pfsockopen("ssl://myhostsite", 22);
or
$persistent_socket = pfsockopen("ssl://myhostsite", 989);
#user260294: Thank you so much for http://phpseclib.sourceforge.net/. Although unrelated to original question, it saved me hours of coding on a similar project.
#Simon: You haven't seen anyone using pfsockopen() specifically with SSH / SFTP due to the fact that it does not work for these specific protocols. The idea is that if a connection already exists you are able to reuse it with pfsockopen without resending any headers, but this is not allowed with daemons listening on port 22. You have no other choice but to reestablish the connection and resend the headers. This applies to anything that deals with SSH1/2/SFTP.
In the case of a daemon that establishes a persistent connection - when it times out you have to reconnect all over... So I don't see much of a point in doing that.
Here's an SSH / SFTP wrapper class around fsockopen():
http://phpseclib.sourceforge.net/
It's not pfsockopen() but maybe replacing the one fsockopen() call with pfsockopen() will do the trick?
wow the package at http://phpseclib.sourceforge.net/ works perfectly for sftp connection and no need to install or add modules or anything. It just works. Thanks sooo much
I Dont know of a class implementation built around that but there is an ssh2 module if that helps you...

Categories