We are using PHP and fsockopen() to check if a host is available. It works great for standard ipv4 addresses, but recently we started adding ipv6 addresses and it fails. According to the PHP documentation for fsockopen() we simply just need to enclose the ipv6 address in brackets for ipv6 support.
fsockopen('[2a03:b0c0:3:d0::14a:e001]', 80, $return_error_number, $return_error, 10);
However, we are always getting:
Network is unreachable
Does the server running PHP need to support ipv6 as well for this to work? Any other gotchas?
Network is unreachable
This is an error message of the underlying infrastructure and is most likely not produced by PHP itself. It means that the network trying to be reached (in this case the IPv6 global scope) cannot be communicated with. This is usually due to misconfiguration or failure to implement IPv6 by the ISP.
Does the server running PHP need to support ipv6 as well for this to work?
Yes. Very much so. Think of network protocols as languages spoken over phone lines; if two callers don't speak the same language they won't be able to understand each other and hence their information will be mutually unreachable.
There are however services that let you NAT or embed IPv6 within IPv4, maybe even by your ISP. Such offers are usually titled "IPv6 tunnel" or similar. Inquiring about IPv6 at you ISP is usually a good first step - professional server hosters and datacenters will often provide an option to enable or order basic IPv6 through their customer panel.
Check if IPv6 is properly configured for your particular environment or if you want to utilize a tunnel service. If there is no other simple way for you to get global IPv6 connectivity, then you will probably not be able to get your code to work.
A great stackexchange community for server configuration of any kind is https://serverfault.com/ and many questions about IPv6 have already been answered there.
Related
I am running into an issue in relation to security and verification. I have a software that checks to confirm a user, and I need to make sure it's the same client sending a PHP request and a node server request. However, on the node server, the client's IP is shown in IPv4, and on the PHP it is shown in IPv6. Is there any way I can get the same output somewhere, for example extract the IPv6 on the node server, or the IPv4 on the PHP server? Thanks.
Obtaining the same IP or verifying that it is the same client despite a "different" IPv4 and IPv6
The problem is that IPv6 and IPv4 are not coupled in any way. There's no way to deduce a v6 address from the v4 address or the other way around.
In my humble opionion, verifying users by their IP addresses is something you should avoid as IP addresses are spoofable, and the practice leads to these kind of issues. That said, there are a couple of "solutions".
Disable IPv6 on the webserver that's hosting the PHP application. Since you haven't mentioned which type of webserver this is, you should be able to google something like 'disable ipv6 apache' on how to achieve this. This should garantuee an identical IPv4 address on both servers. I personally don't particularly like this solution as it hinders IPv6 adoption.
Enable IPv6 on the node server. Please note that clients can still prefer IPv4 over IPv6 for any reason at all and there's no way to garantuee that it will use IPv6 to both webservers.
You could proxy all calls from one webserver to the other and pass the original IP in for example an 'X-Forwarded-For' header. This will introduce some overhead, but the source IP will be stabler.
Personally, I'd shy away from using the IP address and implement some sort of token stored on the client that can be verified on both servers by means of a shared database if that is an option.
I have created a web app through azure that entirely depends on a users location to give them the correct data e.t.c. It's an app that recommends places to go locally.
I'm using azure, cloudflare and codeigniter as the frame work.
I'm really getting stressed out, as when i'm home, i'm getting the right location, but the second i go on my website anywhere else, it never gets the accurate information.
When cheking the header $_SERVER['HTTP_CF_CONNECTING_IP']; i seem to be getting an ipv6 address, when i go to ipdata.co, their site loads my ipv4 address which gives exact accurate information. But when i enter the address from $_SERVER['HTTP_CF_CONNECTING_IP']; it gives me city null and every other option as null
does anyone have any suggestions on how to get the users IPV4 address through cloudflare and azure?
Or any suggestions on other ways to do this? It's prolonging the launch of my website.
I am pretty new to understand geo-location and ip addresses and all that, so please bare that in mind.
Thanks
The reason that you are getting IPV4 address from your home and IPv6 from somewhere else as by default, Cloudflare provides free IPv6 support to all domains without requiring additional configuration or hardware. If your origin web server is not compatible with IPv6, Cloudflare allows toggling IPv6 Compatibility to Off. You can disable the IPV6 Compatibility to Off from cloudflare.
Reference: https://support.cloudflare.com/hc/en-us/articles/229666767
Cloudflare put into this header whatever the connecting client IP is, so they really have little control over what the user-agent decides to do.
Also check if your network has ‘good’ IPv6 connectivity, or are you getting sub-optimal routing compared to IPv4.
Check this link for additional reference.
http://www.webhostingtalk.com/showthread.php?t=1692173
I have set up a websockets chat with the purpose of learning. Everything is working but I can't figure this issue out.
When I supply 127.0.0.1 as the address of the connection on the client side then I can access the server from the computer that's hosting it, but when I change the address to the actual LAN address of the hosting computer I can't connect the server even from the host itself. See:
Server = new FancyWebSocket('ws://127.0.0.1:9300'); Appears to work but only the computer that's hosting the server can connect ( for obvious reasons )
Server = new FancyWebSocket('ws://192.168.1.3:9300'); No computers can connect. I confirm 192.168.1.3 is the LAN address of the hosting computer.
What address do I need to put in there so that other computers from my local network can connect?
I solved the problem. Since it was a combination of two answers I thought the only fair thing to do was add another answer with an explanation.
As #Mehran suggested, I have had the server address set up as 127.0.0.1 instead of the network address. After changing that to 192.186.1.3 I was able to connect from the server itself, but other machines were unable to connect. Then I did the steps from the guide provided in #vtortola's answer to add a new inbound rule into the server's firewall in order to allow that port to be used.
So finally it all works now, thank you very much for helping me. +rep to everyone!
I'm pretty sure this is due to the configuration of your WebSocket server. It must be listening to localhost (127.0.0.1) to accept incoming connections in which case it won't answer to those aiming 192.168.1.3.
Since you didn't mention which server you are using I can not be specific but in general there are two ways to instantiate a listening socket, binding it to a specific IP address or * to bind whatever addresses system has. You need to configure the later if you intend to answer server connections coming from any computer within your LAN.
It looks like a Firewall/Policies issue to me.
IIS 7 Windows 2008, Localhost work but not local ip or external ip
Your TCP 80 could be allowed because the IIS installation will open it, that will explain why normal web browsing works. But you are trying to connect to the TCP 9300, that is very unlikely that is allowed by default.
Give a try to this: How to Open a Port in the Windows 7 Firewall , and allow that port.
Here are some things that you can safely assume while troubleshooting this issue:
If the service is able to work on 127.0.0.1 on the same machine, you can assume that the problem is not in the code or the PHP configuration
If you are not receiving an error when the server tries to bind to 192.168.1.3:9003 you can safely presume that the service is working. Try opening the Resource Monitor to see if it is actually listening on this port to confirm. To do so, go to 'Start Menu' in Windows and type 'Resource Monitor' in the 'Search programs and files' box. After opening the Resource Monitor, click the 'Overview' tab and find the name of the server process (typically 'php' if your using a CLI). With your process selected, switch over to the 'Network' tab and you will be able to see if it is listening on any ports within the 'TCP Connections' panel. This will show you what address and port it is listing on, as well as the remote address and port of any clients connected to the service.
If you know the server is running, and you know that it is actively listening on the expected address and port, it is very likely a firewall issue within Windows or your router. Note that even though 192.168.1.3 is the IP assigned to your interface, this is not a local IP and all communication to and from 192.168.1.3 will still go through the Windows firewall, including if being sent on the same machine. If your already at this point, I would strongly suggest checking your windows firewall first. If it is not the Windows firewall, check your router to see if it is blocking the port, and also check port forwarding and other setting to make sure that the router isn't otherwise interfering. We can likely help you with router issues here, but have your router's manual handy.
HTTP is a common service port so it is very possible that the router is not blocking the port, and windows may have automatically opened it if you are using IIS. 9300 is not a common port so it is unlikely to be open by default under any situation, unless your default is "all in", which effectively means your not using a firewall.
Another thing you might try (if possible) is closing your existing HTTP service and bind to port 80 using your Websocket service, or if possible (and while exercising caution) turn off your windows firewall completely to see if it works long enough to connect.
In general, don't try to reach your local network IP address from your own machine. There are very confusing things that happen at the socket layer here that I'll try not to delve too far into. The OS goes out of its way to make this work. Sometimes. I would expect that you cannot reach 192.168.1.3 (the server I'm assuming) from itself. There's a translation between local endpoint addresses when you do that which complicates everything.
A network switch will typically not send a frame back down a port it just received it from, so what you're seeing when you ping your local IP in cmd prompt is a loopback shortcut the OS is taking.
Not being able to reach it from another machine causes me suspect that the socket is not bound correctly on the server. Double check that you are explicitly declaring the socket on the server (address and port), and that your're binding your listener to that socket. Also ensure that the address you're binding to is for the correct network adapter. I see this all the time with laptops or machines that have multiple connected adapters.
Unfortunately I cannot be more targeted with my response as I am unfamiliar with what a FancyWebSocket is or how it is constructed.
I can help you if its a linux system.
If there is no name server on the local network, it is still possible to establish a small table mapping IP addresses and machine hostnames in the /etc/hosts file, usually reserved for local network stations.
This file is available even during network outages or when DNS servers are unreachable, but will only really be useful when duplicated on all the machines on the network. The slightest alteration in correspondence will require the file to be updated everywhere. This is why /etc/hosts generally only contains the most important entries.
This file will be sufficient for a small network not connected to the Internet, but with 5 machines or more, it is recommended to install a proper DNS server.
Try adding all the 'ip:port' along with a hostname and copy the template in file /etc/hosts in all the system.
Hope it resolves the issue!
I'm trying to set up PHP websockets on my website. This works great on my local WAMP server, but on my website I keep getting a warning:
unable to bind address [98]: Address already in use in"
I tried various libraries, but they all return this error.
My guess is that the port I'm using in isn't free. The problem is, that I cannot access terminal since this is a shared server (according to phpinfo() websockets are enabled, btw) so I can't look for free ports. Also tried to use port 0 - but no luck.
Thanks in advance!
EDIT:
For instance, this is some code using https://github.com/Flynsarmy/PHPWebSocket-Chat
// start the server
$Server = new PHPWebSocket();
$Server->bind('message', 'wsOnMessage');
$Server->bind('open', 'wsOnOpen');
$Server->bind('close', 'wsOnClose');
// for other computers to connect, you will probably need to change this to your LAN IP or external IP,
// alternatively use: gethostbyaddr(gethostbyname($_SERVER['SERVER_NAME']))
$Server->wsStartServer($_SERVER['SERVER_ADDR'], 9300);
Well, Bluehost site writes: "We block access to certain ports to help avoid having security holes in the firewall...Purchasing a dedicated IP will allow us to grant you access to the ports you will need to run your specific services on.". The technical support guy told me otherwise. I guess case is closed. Thank you all for your time!
talhof9 I went through similar pain in trying to configure my shared hosting service, I didn't find a direct solution to get a shared *AMP server to support WebSockets, but I found a workaround that will at least let you test the commercial viability of the solution you are putting together (if that is indeed what you are looking for) without paying for all the headache of setting up,configuring and administering your own VPS.
Check out http://www.pusher.com for an easy websocket deployment library, that uses their Node server. The free sandbox version lets you play around to get it working, and once you want to test commercial viability you can upgrade to a paid plan.
Hope this helps!
(note I do not work for Pusher)
Most probably your hosting provider has, somehow, disabled PHP sockets. This makes sense because PHP is used to process webpages not create daemons and you're probably using a regular web hosting plan (not a dedicated server).
I would check in with your hosting provider - support forum or just call them.
i'm using opencart on a virtual host with a dedicated ip. bank allows virtual pos queries only from dedicated ip, but server ip is used by php to communicate with bank's api. is there any way to force php to use that dedicated ip?
ps: there is a in-code solution, however i prefer more general solution like as php.ini edits.
The proper way is to bind() your connecting socket to the IP address of the interface you wish to use. This will guarantee the behavior you want. (You can set the port number to zero to have the OS choose one.)
You can also make the OS pick the interface appropriately. In fact, I'm surprised it is not. You didn't list any specific IP addresses, interface configurations, or a routing table, but if we assume your private IP is 172.16.0.222 and the bank's IP address is 172.16.0.11, then opening a connecting socket to 172.16.0.11 should use your local private IP address. If it's choosing your public address, then the OS thinks it has a route from that address to the destination. Make sure that is not the case and your problem should be fixed.