PHP:在 Apache 中运行时,gethostbyname() 突然不再将名称解析为 IP

PHP:在 Apache 中运行时,gethostbyname() 突然不再将名称解析为 IP

我们的一个旧服务器没有进一步更新或重新配置,当在 Apache 中执行 PHP 时,它突然停止将主机名解析为 IP。但是,从 CLI 执行时它仍然可以正常工作。

根据 RSS 缓存的最后修改时间,我推断它在 3 月 28 日左右停止工作。

为了重现该问题,我创建了一个脚本fsockopen(),它显示“连接失败(errno 2)”。我进一步将问题归结为与名称解析失败有关:

<?php $addr = gethostbyname("twitter.com"); echo "ADDR($addr)"; ?>

当我通过 Apache 运行它时,输出是ADDR(twitter.com),这是错误的。

当我从 CLI 运行该程序时,输出包含ADDR(aaa.bbb.ccc.ddd)不同的 IP 地址,正如预期的那样。

服务器设置没有任何变化。CLI 和 Apache 模块共享相同的php.ini。PHP 版本为 v4.4.9,Zend Optimizer 为 v2.5.10。Apache 为 v1.3.31。

我知道版本很旧。但是由于没有任何变化,像“先尝试升级版本”这样的解决方案并不是解决方案,因为服务器的功能集/版本已冻结并将很快被替换。我们仍然需要一个解决方案。

如果我运行dig该脚本,它会在两种环境(mod_php 和 CLI)中运行,但这不仅仅是一个丑陋的黑客行为,因为它会涉及整个脚本库的大量编辑和测试,这也是不受欢迎的,因为服务器上的 PHP 应用程序也被冻结,并且只接收安全更新。它将被完全重写(在新服务器上)取代。

但是由于重写需要一些时间,并且需要连续替换旧应用程序的部分内容,因此我们需要修复解析器问题。我已经在 Google 上搜索了一下,虽然这个问题是已知的,但很多人没有找到解决办法。提高内存限制的修复方法不起作用。重新启动也不起作用。mod_php 中的解析器确实无缘无故地停止工作了。:-(

更新:同时,我通过完全停止 Apache、等待片刻然后重新启动来解决了这个问题。但这并不能解释这种行为的根本原因(因此没有令人满意的解决方案)。所以我把这个问题留着不管。

答案1

无论是正常重启还是正常重启都不起作用。我需要完全停止 Apache,等待所有进程完成,然后重新启动 Apache。问题解决了。由于似乎没有人能找到这种行为的根本原因,所以我接受了自己的解决方案。

答案2

同样,从 CLI 运行时正常,通过 Apache 运行时出错。我猜这与名称服务器的更改有关,例如在 /etc/resolv.conf 中。不知何故,Apache(其他程序也受到影响)不检查更改的名称服务器,无法解析。当我用笔记本电脑切换网络时,就会发生这种情况。我必须手动停止 apache、opera、firefox 等,以便它们获取新的名称服务器设置。

答案3

我的问题出在我们设置本地服务器虚拟机和 chroot 环境时。自 1998 年以来,生产服务器从未出现过任何问题。

不知何故,虚拟机的用户权限完全错误(作为desktop_user_r)。

我需要对 chroot 中的所有文件夹执行 chown apache:root /*。这可能需要对根目录中的所有文件夹执行(或者至少验证 apache 是否具有足够的权限来访问“/etc”和“/etc/resolv.conf”文件夹(以及其他文件夹)。

注意:我们不必重新启动 apache,更改权限就足够了。

答案4

来自PHP.net 手册中的 gethostbyname

如果 apache2、mod_chroot 和 php5 的名称解析失败,请将 LoadFile /lib/libnss_dns.so.2 添加到 mod_chroot 配置中。

在 RedHat Linux 上的 chroot 环境中使用 PHP 和 Apache 时,我发现需要绑定挂载 /var/run/nscd 才能使其正常工作。显然,该目录中的套接字是所有 DNS 事物所必需的。

相关内容