PDA

View Full Version : PHP unable to resolve host names


dlst
06-26-05, 19:33
On my web box I have a problem with PHP resolving host names. Host names resolve perfectly from the command line:

<?php
// http://www.php.net/ is 64.246.30.37
$fd = fopen( "http://www.php.net/", "r" );
if( !$fd )
{
echo "Cannot open URL";
} else {
while ( !feof( $fd ) ) {
$buffer = fgets( $fd, 4096 );
echo $buffer;
}
fclose ( $fd );
}

?>

produces the following error codes:

Warning: fopen(): php_network_getaddresses: getaddrinfo failed: Temporary failure in name resolution in /hsphere/local/home/XXXuser/XXXXXXX.com/test/test.php on line 3

Warning: fopen(http://www.rackspace.com/): failed to open stream: Resource temporarily unavailable in /hsphere/local/home/XXXuser/XXXXXXX.com/test/test.php on line 3
Cannot open URL

that seem to be described in php.net as bug 11058:

http://bugs.php.net/bug.php?id=11058

The code is supposed to read the remote site home page instead of failing the dns query.

I ran this code on another server and it did work, I am running RedHat's default php 4.3.2.

I ran this script successfully on the command line (on the problem server) using psoft's php build with:

/root/php/php-4.3.11/sapi/cli/php /hsphere/local/home/XXXuser/XXXXXX.com/test/test.php

This command line php reads /usr/local/lib/php.ini while the php apache module loads /hsphere/local/config/httpd/php.ini.

That made me believe that either the php apache module had a problem or apache itself when resolving names.

When I traced the system calls in the command line, the client uses the system's dns:

connect(3, {sa_family=AF_INET, sin_port=htons(53), sin_addr=inet_addr("X.X.X.X")}, 28) = 0

when I traced apache's php, I saw the same atempt of connection to a different set of nameservers:

[pid 4509] connect(13, {sa_family=AF_INET, sin_port=htons(53), sin_addr=inet_addr("X.X.X.X")}, 28) = 0

(where X.X.X.X is the IP address of the physical box, not the Nameservers)

[pid 4509] connect(13, {sa_family=AF_INET, sin_port=htons(53), sin_addr=inet_addr("Y.Y.Y.Y")}, 28) = 0

(where Y.Y.Y.Y is the IP address of another physical box, not the Nameservers)

This is what happened right after:

[pid 4509] recvfrom(13, 0xbfff85c0, 1024, 0, 0xbfff7ad8, 0xbfff7a90) = -1 ECONNREFUSED (Connection refused)

Instead of seeing:

recvfrom(3, "\27h\201\200\0\1\0\2\0\4\0\4\3www\3php\3net\0\0\1\ 0\1\300"..., 1024, 0, {sa_family=AF_INET, sin_port=htons(53), sin_a
ddr=inet_addr("64.49.236.16")}, [16]) = 214

The conclusion is that php is attempting to resolve using the incorrect nameservers, but the command line resolves just fine.

This is where I hit a wall. Does anyone have any advice on where to go next? I've already filled out a trouble ticket with Psoft, but this is the third time they are claiming "your configuration is fine because hosts resolve from the command line"... pretty useless considering the information above.

Anyway, hopefully someone here can help! Thanks!

dynamicnet
06-27-05, 05:01
Greetings:

I would try the following:

What happens when you add the domain you want to resolve to /etc/hosts ?

What happens if you backup /etc/resolv.conf and use different name server IP addresses?

Also, are you using PHP with safe mode turned on?

Thank you.

dlst
06-27-05, 07:16
Adding to /etc/hosts makes it work just fine.

Replacing /etc/resolv.conf with different name server IP addresses has no effect.

PHP safe mode is not turned on.

Avalon IT
06-27-05, 07:34
Anyway, hopefully someone here can help! Thanks!

Try with "php_admin_flag allow_url_fopen On" for your website, or change it globally in php.ini.

dlst
06-27-05, 07:39
Thanks Avalon. Tried that, no effect. I should mention that CURL (through PHP only) fails to resolve host names, as well as other functions that try to resolve.

dynamicnet
06-27-05, 08:52
Greetings:

1. On Avalon IT suggestion, which is sound and well thought out, please remember to undo the change if it did not help.

It does have security implications.

2. Did you check that the name servers IP's you tried in /etc/resolv.conf work from the command line (i.e. use "host cnn.com" and "dig mx cnn.com" and see if you get valid IP addresses)?

Thank you.

dlst
06-27-05, 09:05
The conclusion is that php is attempting to resolve using the incorrect nameservers, but the command line resolves just fine.

Thanks for the tip about undoing changes made in the course of testing, I'll be sure to be careful.

Avalon IT
06-27-05, 10:33
Thanks Avalon. Tried that, no effect. I should mention that CURL (through PHP only) fails to resolve host names, as well as other functions that try to resolve.

Hm, off the top of my head thats the only PHP option I know off that has anything to do with blocking connections to the remote sites. Did you tried to connect to 64.246.30.37 instead of www.php.net?

BTW, you should verify that resolving works with appropriate functions, fopen() is not used for that and your example will fail if your server doesn't permit connections to the remote websites because of allow_url_fopen, firewall, or something else.

Try with something like this, this will test your resolving without trying to actually connect to that particular remote website, which is another issue:

<?php
$ip = gethostbyname('www.php.net');
echo $ip;
?>

dlst
06-27-05, 10:48
Using the IP address instead of www.php.net for fopen causes the following error:

Warning: fopen(64.246.30.37): failed to open stream: No such file or directory in /hsphere/local/home/wwwuser/bookjam.com/test/test.php on line 3
Cannot open URL

gethostbyname('www.php.net') fails, but does not report an error. It returns "www.php.net", not the IP address.

This is consistent with the tests above... PHP is incapable of resolving domain names.

Avalon IT
06-27-05, 12:32
This is consistent with the tests above... PHP is incapable of resolving domain names.

Not only that, your mod_php seems to be incapable of connecting to the remote servers too if fopen() doesn't work.

I suppose you didn't run php-cli as httpd user, thus thats the difference between php-cli and mod_php results? If thats the case try to run this, asuming your Apache runs under httpd username:

sudo -u httpd /bin/sh -c "php -n test.php"

dlst
06-27-05, 12:39
I get a "php: command not found".

dynamicnet
06-27-05, 12:41
Greetings Daniel:

Normally I don't have a lot of free time <smile>, but today was one of those exception days.

1. I verified the test code did not work (have heart) "as is" on our H-Sphere isntallation which is relatively secure.

2. I verified, and Avalon IT already knew this, that changing "allow_url_fopen" to On (from off); AND making sure it was not listed in the disable functions list did the trick to get the test code to work.

That stated, I would recommend resting by temporarily (key) editing /usr/local/lib/php.ini on the server in question to

allow_url_fopen On

And making sure this function is not disabled. Then restart Apache and test.

IF this works, then change the value to "Off" in /usr/local/lib/php.ini and then create a directory wrapper in /hsphere/local/config/httpd/httpd.conf to just allow it for those directories (on down; auto inheritance) that need it.

The "allow_url_fopen" is one of those code elements that can be highly abused by hackers.

Thank you.

Avalon IT
06-27-05, 12:46
I get a "php: command not found".

Try with /usr/local/bin/php or something like that, it depends on where your php binary is.

dlst
06-27-05, 12:51
Avalon, what if I just get a new copy of 4.3.11 and do a custom recompile of PHP (or rather, have it done by dynamic, or whoever else wants the job)? What are the chances that would nip this one?

dlst
06-27-05, 13:31
Psoft to the rescue:

>This command line php reads /usr/local/lib/php.ini while the php apache
>module loads /hsphere/local/config/httpd/php.ini.
Actualy /usr/local/lib/php.ini is just a link to /hsphere/local/config/httpd/php.ini
==================
[root@web root]# ls -la /usr/local/lib/php.ini
lrwxrwxrwx 1 root root 35 Jun 14 03:10 /usr/local/lib/php.ini -> /hsphere/local/config/httpd/php.ini
[root@web root]#
=================

I hav eremoved incorrect IPs from resole.conf file and now
http://www.XXXXXX.com/test/test.php
works fine. Please check it.

-----

I'm still testing, but it looks like things are working properly again. I'll post again here when I've confirmed, thanks.

Avalon IT
06-27-05, 13:46
Avalon, what if I just get a new copy of 4.3.11 and do a custom recompile of PHP (or rather, have it done by dynamic, or whoever else wants the job)? What are the chances that would nip this one?

You could try, they can check other things while loged in, but I don't think that 4.3.2 version is the problem.

dynamicnet
06-27-05, 14:10
Greetings Daniel:

Yes, we could easily do a recompile / custom compile if needed.

Please just keep in mind that if the allow_fopen_url works to turn it off globally in /usr/local/lib/php.ini and then restrict it to those applications by directory that need it.

Thank you.

I'm still testing, but it looks like things are working properly again. I'll post again here when I've confirmed, thanks.

dlst
06-27-05, 15:01
Indeed, that seemed to do the trick. Regarding the Psoft reply... "resole.conf" is a typo... the file doesn't exist. I think they meant resolv.conf, but if they did, I already checked that and it was right before they "fixed" it. I have the funny feeling that whatever magic they did, it didn't have anything to do with that... but at this point I don't care, I'm just glad it's working!!