Access raw Apache webserver request - php

I intend to design a web gps tracking application. the gps transmits data using TCP (no HTTP headers) on port 7070 (which I intented to change to 80). I know the protocol for communication between the GPS tracker and client, however i am stuck as i cannot intercept the datapacket on webserver.
Since application is in development stage and me being a hobbyist, I cannot afford a dedicated web host server and thus get access to php-cli interface for socket programming.
is there any way i can circumvent the need for php-cli and intercept the raw tcp packet.
Thanks

Simply have a dedicated PHP script listening on port 7070, which you can accomplish with fsockopen(). You don't want to have your GPS sending directly to port 80 when Apache's already listening on port 80. Apache'll see a non-HTTP set of data come in and ignore the request completely.
$handle = fsockopen('localhost', 7070, $errno, $errstr);
if (!$handle) {
die("Couldn't bind to socket (err $errno): $errstr");
}
while($data = fgets($handle)) {
... process gps data ...
}
would be the very simplest basic form of this.

Related

Creating PHP relay using sockets between multiple clients and servers

I've got a Python server which multiple clients connect to using sockets. At the moment one server isn't able to cope with the load so I'm looking at ways to split the clients up according to some criteria such as their username.
The intention is to put clients with usernames starting with A-G on server 1, H-P on server 2 and P-Z on server 3.
What I'm trying to do is to write a process that will listen for connections on port 45000 and will then forward those on to the appropriate server on 45001, 45002 and 45003.
At the moment, when a client connects to the original server they connect via a TCP port e.g. 45000. The server checks that they are authorised and responds on a random port with a handshake e.g. 59117, 60647 or 61573.
The response port is not specified when the client first connects so my question is, when is the value determined and how does the client know to listen on that port for the reply ?
So far I've written a PHP process which takes the data from the clients and forwards it to the appropriate server but I can't work out which port to listen on for the response back from the server. Is there some way that PHP sockets can negotiate the response port so that it can be stored in a variable in my script ?
Here's my basic connection code in PHP. I have no knowledge of Python so this is going to have to be done in PHP:
// Define remote Server
$socket=socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
// Open socket on remote server to send $buf data to
socket_connect($socket, 'X.X.X.X', 40149);
echo ("Forwarding data ($buf) to $socket ....\r\n");
$bytesWritten=socket_write($socket, $buf, strlen($buf));
echo ("Wrote: $bytesWritten bytes\r\n");
// Now listen for response but this will be on another socket
// How do we know what this is ?
if (false === ($response = socket_read($socket, 16384))) {
echo ("Response: $response\r\n");
}
This is way out of my comfort zone so I may have this completely wrong but an afternoon spent Googling has turned up any answers yet.

Redirect an octet stream in Apache using PHP or Django

I have a webserver which serves the client with an octet stream on port 20000 (it's actually a socket.io server hosted with node.js). This is running on a shared hosting account with a regular Apache server running on port 80 (this cannot be turned off, hence the socket.io server is on port 20000). Due to firewalls and such, I cannot expect the user to be able to connect to port 20000 (or any other than 80). So, how can I serve the client with the octet stream produced by the socket.io server from the Apache server (sort of like a reverse proxy)? Unfortunately I cannot use mod_proxy on my Apache server given restraints of my hosting plan. I was thinking I could do this with a PHP page that opens a socket somehow.
Update: I also have Django for Python 3 installed on my server which could be useful. Please note that the proxy cannot simply request the target page and serve it back to the client since the data has to be transferred in real time.
Re "it cannot simply serve the target page back" ... this is not true because this is all an HTTP proxy is. Most protocol proxies use a socket (versus a file or pipe) and simply copy the data from socket to socket. An HTTP proxy does the same thing except every HTTP request requires a handshake, so the proxy will require a few packets back and forth before reaching the payload. You can create an HTTP GET proxy very easily in django. A POST proxy will need extra footwork.
I am not familiar with Socket.IO, but upon researching ... how does socket.io work? ... it appears it uses only "old" HTTP features and runs everything as REST. The REST is encapsulated as a transport inside of a persistent socket.
If you were looking for an TCP or IP-level proxy within Django, its not going to happen. Your apache server, and then WSGI/CGI/whatever closes the TCP socket off from you. The only way you'll be able to access it is with sufficient permissions to those parts of the server.
Here's what I'd do ... In django make a url pattern that captures the socket.io api, and have it connect to a view that does something like the following (untested pseudo code):
import urllib2, mimetypes
from django.http import HttpResponse
def ForwardToSocketIO(request):
# Capture the URL pattern
path = request.get_full_path()
# Create a URL opener
response = urllib2.urlopen('http://localhost:20000%s' % path)
# Capture and return response
django_response = HttpResponse(response.read())
django_response['Content-Type'] = 'octet-stream'
return django_response
Hope this helps. I don't have an octet stream available so apologies for not testing.
Seems possible not impossible. I have not done it before but know the way to do but again I don't know the impact of Firewall on port openning and closing. The basic Idea about doing thing is:
Get you request from port 80 to do things and for response of that request use different port to communicate with client. It would become a tunnel to recieve request from one port and get reply from the other port. Only one thing to be properly taken care of that termination of connection as soon as possible once the purpose is resolve unless it would create memory load on the server.
With the below example you can do the above things but suggest you to use them with caution and after proper testing.
ref: Programming with Sockets through PHP
This example shows a simple talkback server. Change the address and port variables to suit your setup and execute. You may then connect to the server with a command similar to: telnet 192.168.1.53 10000 (where the address and port match your setup). Anything you type will then be output on the server side, and echoed back to you. To disconnect, enter 'quit'.
<?php
error_reporting(E_ALL);
echo "<h2>TCP/IP Connection</h2>\n";
/* Get the port for the WWW service. */
$service_port = getservbyname('www', 'tcp');
/* Get the IP address for the target host. */
$address = gethostbyname('www.example.com');
/* Create a TCP/IP socket. */
$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
if ($socket === false) {
echo "socket_create() failed: reason: " .
socket_strerror(socket_last_error()) . "\n";
} else {
echo "OK.\n";
}
echo "Attempting to connect to '$address' on port '$service_port'...";
$result = socket_connect($socket, $address, $service_port);
if ($result === false) {
echo "socket_connect() failed.\nReason: ($result) " .
socket_strerror(socket_last_error($socket)) . "\n";
} else {
echo "OK.\n";
}
$in = "HEAD / HTTP/1.1\r\n";
$in .= "Host: www.example.com\r\n";
$in .= "Connection: Close\r\n\r\n";
$out = '';
echo "Sending HTTP HEAD request...";
socket_write($socket, $in, strlen($in));
echo "OK.\n";
echo "Reading response:\n\n";
while ($out = socket_read($socket, 2048)) {
echo $out;
}
echo "Closing socket...";
socket_close($socket);
echo "OK.\n\n";
?>

Why are UDP Packets not Sent from a Client Web page to a Server Using PHP fsockopen?

The following code sends out a UDP packet when I run it from my Linux server with the address of my web client udp://192.168.1.107:2159. However, when I call the same web page from the client with the address Linux server address shown in the code, NO UDP packet is emitted. I tried both a PC client with chrome and a Mac client with Safari. Also, the phpinfo() shows that allow_url_fopen is "On". Also, I tried the code without the fflush() function too.
Is there restrictions on Client web pages and PHP sockets? I don't see this searching the net. By the way, I coded a Java app on the same client machine and it sends the UDP packet to the address and port without problem.
phpinfo();
$errno = 0;
$errstr = "";
$fsocket = fsockopen("udp://192.168.1.103:2195", $errno, $errstr);
if( !$fsocket ) {
echo "$errstr( $errno)<br/>\n";
} else {
$out = "Oh ya baby!\r\n";
fwrite( $fsocket, $out );
fflush( $fsocket );
fclose($fsocket);
}
The port is the second argument to fsockopen(). It needs to get passed isolated from the domain name. Like this:
$fsocket = fsockopen("udp://192.168.1.103", 2195, $errno, $errstr);
The issue... You can't always believe Wireshark! I trusted Wireshark too much. I created a Java application to receive from the Web based PHP fsockopen packet transmission. Low and behold, Java catches the packet and Wireshark missed the packet - every time too. The Wireshark case that failed was Mac (client PHP web call), Linux (Wireshark session and PHP web server).
I don't know if Wireshark labels the packet as something else or there is something obscure in the PHP generated packet as far a Wireshark is concerned? The weird thing is when I transmit the same packet from a Java application Wireshark catches it! I do not know all the reasons why. But I got PHP fsockopen to work so my job is done! It works between Linux and Mac OS 10 in all combinations of client and server, so great!

PHP fsocketopen Though Proxy

I am currently using PHP to open up a port 43 connection to get whois information directly from a registry using this code.
// connecting to the whois server.
$handle = fsockopen($server, 43);
if (!$handle)
return false; // connection failure
//asking the server
fwrite($handle, $domain_name."\r\n");
// getting response
$response = '';
while (!feof($handle))
$response .= fgets($handle, 1024);
fclose($handle);
It works great however I want to connect though a proxy server so I route my intertent connection through it. If this were able to use cURL I would use curl_setopt($curl_handle, CURLOPT_PROXY, $ip_address . ':4040'); but i can not find a way to do this using fsocketopen. How can I accomplish this either with cURL or fsocketopen()?
Sockets dont have proxy. Just gateways and routers are in-the-middle (if any). You were talking about cURL, that it has proxy - it only uses http/s proxy service. For example, if you have http proxy service on server example.com:8080 you first need to open connection to server example.com (socket) on port 8080 and then send your request, proxy will forward your request and return response. In your case, you just open tcp connection on port 43 on specific host and exchange data directly with target server. If you dont want to do this directly and reveal your ip (or something) you'll need some service too. If you have access to other machine you could use it to do the job. If you want to do it manually you could use ssh or something like that, if you want to make it automatized, you'll probably need to write service on your middle server because you probably wont find any public proxy servers with other protocols than popular http, ftp, ...
Hope this helps.
By the way I see no reason why you should use proxy on whois service.
You could use a SOCKS proxy to relay the TCP connection from your machine to the SOCKS server to the WHOIS server but you would have to implement the SOCKS communication protocol over fsockopen.
Another method would be to use ProxyChains on the server and execute it via PHP. I've answered a similar question here ( How to capture and feed telnet using php and shell scripting? ) which shows how to invoke proxychains from PHP to execute a WHOIS command on a remote server and read the response.

Reusable socket

I tryed to create a socket in php and reuse it from other process.
I know this can be done with a daemon script but I want to do this without.
I created a socket and binded it to a specific port.
$sock = socket_create (AF_INET, SOCK_STREAM, SOL_TCP);
socket_set_option ($sock, SOL_SOCKET, SO_REUSEADDR, 1);
socket_bind ($sock, 'xx.xx.xx.xx', 10000);
socket_connect ($sock, $host, $port);
And from another php file I did the same thing. But the packets that I send from the 2 file are not "validated" by host. I sniffed all ports and I see that it uses same local and destination port. I don't understand where is the problem.
Can you help me with this?
It's ok in any other programming language, or any other solution for this.
Andrew
Sockets are not symmetrical. The server side listens on a specific port for a client to conect - the client does not specify the local port - only the remote port and address. Its nothing to do with the language you implement it in.
There's a very good socket server implementation available at http://www.phpclasses.org/browse/package/5758.html with examples.
C.
You can't really use persistent sockets in php. When you execute a php file, a new process is created which cannot access the variables - or sockets - of a different php process so it won't know if there already exists a socket and just creates it.

Categories