TLS with php server socket - php

Hi
My proplem is that I have a open socket in my server side code (written php) and I need to trasform this socket to use TLS, with negotiation and decription of the stream before passing it to the already existing code that work with a clear stream without encryption.
What is the simplest solution to archive this?

PHP supports TLS/SSL listening using a stream context. Something like this should work:
$listenstr = "tls://0.0.0.0:1234";
$ctx=stream_context_create(array('ssl'=>array(
"local_cert"=>"mycertandkey.pem",
"passphrase"=>"badpassphrase"
)));
$s = stream_socket_server($listenstr,$errno,$errstr,STREAM_SERVER_BIND|STREAM_SERVER_LISTEN,$ctx);
$conn = stream_socket_accept($s);
// do stuff with your new connection here

Related

How to implement OpenSSL's SSL_Write() by using PHP

I am trying to connect to a server using PHP script. The server is set by SSLv3, I think maybe I need use SSL_Write() to process the message which will send to the server. But I do not find the related function in PHP. So, I wonder which function should I use.
What you are looking for is the TLS stream transport. There is no direct equivalent to the SSL_Write() function; PHP does not implement a functional interface to SSL.
Here is a simple example of using the TLS transport to make a connection to an HTTPS web server. This is not an ideal application of the transport, as PHP already natively supports an HTTPS file wrapper; I'm simply using it here as an example of interacting with a publicly accessible TLS server.
$fh = stream_socket_client("tls://example.com:443", $errno, $errstr);
if ($fh === false) {
die("Failed to connect: error=$errno $errstr");
}
fwrite($fh, "GET / HTTP/1.1\r\nHost: example.com\r\nConnection: close\r\n\r\n"\ );
while (!feof($fh)) {
print fgets($fh);
}
If you need to set specific options on the TLS connection, you can do so by creating a stream context (using stream_context_create()) before making the connection. Refer to the PHP documentation for more details.

Connection to websocket server : OK from javascript, not OK from php

I am using socketio to run a websocket server.
var fs = require('fs');
var options = {
key: fs.readFileSync('/etc/letsencrypt/live/my.domain.be/privkey.pem'),
cert: fs.readFileSync('/etc/letsencrypt/live/my.domain.be/fullchain.pem')
};
var app = require('https').createServer(options)
, io = require('socket.io').listen(app)
app.listen(6666);
Connecting to it from javascript (using socket.io client) works fine.
var socket = io.connect('wss://my.domain.be:6666');
This works also :
var socket = io.connect('https://my.domain.be:6666');
Now I want to connect using php.
I found a simple php client here : How can I send data/text from PHP using WebSocket to process?
But I see no incoming connection when using :
$WebSocketClient = new WebsocketClient('wss://my.domain.be', 6666);
$WebSocketClient->sendData("MyUserNameFromPHP");
And I get the error :
Error: 22145040:Unable to find the socket transport "wss" - did you
forget to enable it when you configured PHP?
When using :
$WebSocketClient = new WebsocketClient('https://my.domain.be', 6666);
I get the error :
Error: 10905616:Unable to find the socket transport "https" - did you
forget to enable it when you configured PHP?
When using tls:// or ssl:// I get no output at all (and still no connection on my websocket server).
So what am I missing to make a websocket connection from my php code ?
https://stackoverflow.com/a/61808878/3701985
please try my answer on another similar thread, I actually tried multiple solutions and now just want to provide answer which worked for me.
https://github.com/ratchetphp/Pawl

Send request to 127.0.0.1 via HTTP which is forwarded on via HTTPS

I am using WampServer (Windows) and PHP pgsql, and apparently something wasn't compiled with SSL support, because I get this error:
Unable to connect to PostgreSQL server: sslmode value "require" invalid when SSL support is not compiled
This got me thinking... I wonder if I can ask pg_connect() to look for 127.0.0.1 on port 12345 (or something like that) using HTTP, and then some middle service could be run on my local system that would pass that on to the server using SSL.
Does anyone know how to do that?
NOTE
I'm trying to connect to the Heroku PostgreSQL server (which uses an Amazon Web Service URL) and requires an SSL connection. I had better luck Googling "amazonws.com postgresql stunnel" for relevant bulletin board messages.
UPDATE
Here is the stunnel.conf file that I used:
;See: https://medium.com/what-i-learned-building/580fdd492119
cert = stunnel.pem
options = NO_SSLv2
options = SINGLE_ECDH_USE
options = SINGLE_DH_USE
socket = r:TCP_NODELAY=1
options = NO_SSLv3
ciphers = HIGH:!ADH:!AECDH:!LOW:!EXP:!MD5:!3DES:!SRP:!PSK:#STRENGTH
[heroku-postgres]
client=yes
accept = 127.0.0.1:YOUR-CHOSEN-PORT
connect = THE-HOST-GOES-HERE:PORT
protocol=pgsql
retry = yes
Reference: https://medium.com/what-i-learned-building/580fdd492119
postgresql does neither use http nor https for its connection, but has its own protocol. But you could use something like stunnel to tunnel a normal tcp connection inside ssl, e.g. if your local pg_client library is not ssl-aware you could create an stunnel on localhost which then forwards the data via ssl to the remote postgresql server.

How to Send File over secure FTP SSL Protocol

I appreciate any help that can be offered on the subject. At the end of an online enrollment, I am taking customer data (several fields), putting them in a CSV file and trying to submit to another client over SSL protocol but have no idea how this is done. I am also storing the information on a local database and am hoping the process is somewhat similar.
I have already been sent links to view the SSH2 instructions from php.net SSN2
but to be honest this is like reading Chinese to me. I do not understand the instructions and am not looking to install any extensions, modify the PHP.ini file or anything of the sort (especially since we do not own the server the information is being sent through).
Is there a simple, secure way of transmitting this file to the SSL protocol provided to us?
Thanks!
Perhaps you could use ftp_ssl_connect for that matter, which is used to open a secure SSL-FTP connection, and to upload a file is just a straight forward process, just create the connection to the server, and put the file up there. A basic example could be:
//Create your connection
$ftp_conn = ftp_ssl_connect( $host, $you_can_provide_a_port );
//Login
$login_result = ftp_login($ftp_conn, $user, $pass);
if( $login_result )
{
//Set passive mode
ftp_pasv( $ftp_conn, true );
// Transfer file
$transfer_result = ftp_put( $ftp_conn, $dest_file_path, $source_file_path, FTP_BINARY );
//Verify if transfer was successfully made
if( $transfer_result)
{
echo "Success";
}
else
{
echo "An error occured";
}
}
For reference purposes http://www.php.net/manual/en/function.ftp-ssl-connect.php
The only way I've managed to do ftp over SSL using php was to use php's exec() function to execute a curl command. PHP's curl library would not work because at the time, the skip-pasv-ip option did not exist and it was something that was absolutely required. Something like:
curl --user <username:password> --disable-epsv --ftp-pasv --ftp-skip-pasv-ip --ftp-ssl --sslv2 --cert <path/to/certificate> -T <path/to/uploadfile> <hostname>
You may need to modify the curl options to suit your needs.

How do you proxy though a server using ssh (socks…) using php’s CURL?

I want to use ssh, something like this:
ssh -D 9999 username#ip-address-of-ssh-server
But within php CURL, but I don't really see how this could be done?
I noticed “CURLPROXY_SOCKS5” as a type in the php site, but guess that wouldn’t work since it isn’t really socks, it’s ssh…
I’m currently using this code:
curl_setopt($ch, CURLOPT_PROXY, ‘ip:port');
But I'm using a free proxy and it’s rather slow and unreliable, I'm also sending sensitive information over this proxy. This is why I want to proxy it over a save server I trust, but I only have ssh setup on it and it’s unable to host a proper proxy.
You can use both libssh2 and curl from within a PHP script.
First you need to get the ssh2 library from the PECL site. Alternatively, the PEAR package has SSH2 support too.
After installing you can then read the ssh2 documentation on setting up a tunnel.
In your script you can then set up the tunnel.
After the tunnel is set up in the script you can specify the CURL proxy.
Perform your CURL operation.
Release the tunnel resource and close the connection in your script.
I'm not a PHP expert, but here's a rough example:
<?php
$connection = ssh2_connect(ip-address-of-ssh-server, 22);
ssh2_auth_pubkey_file($connection, 'username', 'id_dsa.pub', 'id_dsa');
$tunnel = ssh2_tunnel($connection, '127.0.0.1', 9999);
curl_setopt($ch, CURLOPT_PROXY, ‘127.0.0.1:9999');
// perform curl operations
// The connection and tunnel will die at the and of the session.
?>
The simplest option
Another option to consider is using sftp (ftp over ssh) instead of CURL... this is probably the recommended way to copy a file from one server to another securely in PHP...
Even simpler example:
<?php
$connection = ssh2_connect(ip-address-of-ssh-server, 22);
ssh2_auth_password($connection, 'username', 'password');
ssh2_scp_send($connection, '/local/filename', '/remote/filename', 0644);
?>
according to manpage the -D does create a socks proxy.
-D [bind_address:]port
Specifies a local ``dynamic'' application-level port forwarding.
This works by allocating a socket to listen to port on the local
side, optionally bound to the specified bind_address. Whenever a
connection is made to this port, the connection is forwarded over
the secure channel, and the application protocol is then used to
determine where to connect to from the remote machine. Currently
the SOCKS4 and SOCKS5 protocols are supported, and ssh will act
as a SOCKS server. Only root can forward privileged ports. Dy-
namic port forwardings can also be specified in the configuration
file.
You could use ssh2 module and ssh2_tunnel function to create ssh tunnel throu remote server.
Examples available: http://www.php.net/manual/en/function.ssh2-tunnel.php
See my comment on Qwerty's proposed solution. I think you are looking in the wrong direction to try to solve this question. Instead, you should just use cURL and create a personal certificate for yourself. You say you want to use SSH for safety, but why not a certificate instead?
This site will let you easily create one
http://www.cacert.org/
Since it's just for you, you can add an exception to your browsers so they won't complain of a bad certificate. No need for ssh!
To open the SSH tunnel only for the duration of your script, you probably would need to use PHP forks. In one process, open the SSH tunnel (-D - you need to do some work to make sure you're not colliding on ports here), and in the other process, use CURL with socks proxy config. When your transfer is done, signal the ssh fork to terminate so the connection gets torn down.
Keep in mind that while the tunnel is open, other users on the same machine can also proxy on that port if they wanted to. With that in mind, it might be a better idea to use the -L 1234:remotehost:80 flag, and just get the URL http://localhost:1234/some/uri
If things go wrong with this, you may find orphaned SSH tunnels on your server though, so I would call this somewhat fragile.

Categories