Apache网络错误AH00072:make sock:无法绑定到地址
介绍
当有另一个进程在 Apache 配置为使用的同一端口上侦听时,会生成 Apache AH00072: make_sock: could not bind to address 错误消息。 通常,该端口将是用于 HTTP 连接的标准端口 80,或用于 HTTPS 连接的端口 443。 但是,与其他进程的任何端口冲突都可能导致 AH00072 错误。
该错误源自底层操作系统系统的网络堆栈。 问题是在任何给定时间只能将一个进程绑定到端口。 如果另一个 Web 服务器(如 Nginx)被配置为侦听端口 80 并且它正在运行,那么 Apache 将无法为自己声明该端口。
要检测与 Apache 的端口冲突,您需要检查 systemctl 和 journalctl 输出以确定导致错误的 IP 地址和端口。 然后,您可以决定如何解决问题,无论是通过切换 Web 服务器、更改 Apache 使用的 IP 地址、端口还是这些选项的任意组合。
systemctl 故障排除
按照本系列开头的 如何对常见 Apache 错误进行故障排除 教程中的故障排除步骤,当您对 AH00072: make_sock: could not bind to address 错误消息进行故障排除时,第一步是使用 systemctl。
如果 systemctl 不包含描述问题的输出,那么本教程的最后一部分 使用 journalctl 日志进行故障排除 说明如何检查 systemd 日志以找到冲突的港口。
systemctl status 的输出在许多情况下将包含解决错误所需的所有诊断信息。 它将包括 Apache 正在使用的 IP 地址,以及它尝试绑定到的端口。 输出还将指示 Apache 无法启动多长时间,以便您可以确定问题影响 Apache 的时间。
在 Ubuntu 和 Debian 派生的 Linux 发行版上,运行以下命令来检查 Apache 的状态:
Ubuntu 和 Debian 系统
sudo systemctl status apache2.service -l --no-pager
在 CentOS 和 Fedora 系统上,使用以下命令检查 Apache 的状态:
CentOS 和 Fedora 系统
sudo systemctl status httpd.service -l --no-pager
-l 标志将确保 systemctl 输出一行的全部内容,而不是用省略号 (…) 代替长行。 --no-pager 标志会将整个日志输出到您的屏幕,而无需调用像 less 这样一次只显示一个屏幕内容的工具。
由于您正在对 AH00072: make_sock 错误消息进行故障排除,因此您应该会收到类似于以下内容的输出:
Output● httpd.service - The Apache HTTP Server
Loaded: loaded (/usr/lib/systemd/system/httpd.service; disabled; vendor preset: disabled)
Active: failed (Result: exit-code) since Tue 2020-07-28 13:58:40 UTC; 8s ago
Docs: man:httpd.service(8)
Process: 69 ExecStart=/usr/sbin/httpd $OPTIONS -DFOREGROUND (code=exited, status=1/FAILURE)
Main PID: 69 (code=exited, status=1/FAILURE)
Status: "Reading configuration..."
Tasks: 213 (limit: 205060)
Memory: 25.9M
CGroup: /system.slice/containerd.service/system.slice/httpd.service
Jul 28 13:58:40 e3633cbfc65e systemd[1]: Starting The Apache HTTP Server…
Jul 28 13:58:40 e3633cbfc65e httpd[69]: (98)Address already in use: AH00072: make_sock: could not bind to address [::]:80
Jul 28 13:58:40 e3633cbfc65e httpd[69]: (98)Address already in use: AH00072: make_sock: could not bind to address 0.0.0.0:80
Jul 28 13:58:40 e3633cbfc65e httpd[69]: no listening sockets available, shutting down
Jul 28 13:58:40 e3633cbfc65e httpd[69]: AH00015: Unable to open logs
Jul 28 13:58:40 e3633cbfc65e systemd[1]: httpd.service: Main process exited, code=exited, status=1/FAILURE
Jul 28 13:58:40 e3633cbfc65e systemd[1]: httpd.service: Failed with result 'exit-code'.
Jul 28 13:58:40 e3633cbfc65e systemd[1]: Failed to start The Apache HTTP Server.
请注意,如果您使用的是 Ubuntu 或 Debian 派生发行版,其中 Apache 进程的名称不是 httpd 而是 apache2,您的输出可能会略有不同。
此示例 systemctl 输出包括来自 systemd 日志的一些突出显示的行,这些行描述了 AH00072 错误。 这两行都以 (98)Address already in use: AH00072: make_sock: could not bind to address 开头,为您提供有关 AH00072 错误的所有信息,您需要进一步解决它,因此您可以跳过以下 journalctl 步骤,而是继续本教程末尾的 ss 和 ps 实用程序 部分的故障排除。
如果您的 systemctl 输出未提供有关导致 AH00072 错误的 IP 地址和端口的特定信息,您将需要检查 systemd 日志中的 journalctl 输出. 以下部分说明如何使用 journalctl 对 AH00072 错误进行故障排除。
使用 journalctl 日志进行故障排除
如果您的 systemctl 输出不包含有关 AH00072 错误的详细信息,则应继续使用 journalctl 命令检查 Apache 的 systemd 日志。
在 Ubuntu 和 Debian 派生系统上,运行以下命令:
sudo journalctl -u apache2.service --since today --no-pager
在 CentOS、Fedora 和 RedHat 派生系统上,使用以下命令检查日志:
sudo journalctl -u httpd.service --since today --no-pager
--since today 标志将限制命令的输出以仅记录从当天 00:00:00 开始的条目。 使用此选项将有助于限制检查错误时需要检查的日志条目的数量。
如果 Apache 无法绑定到正在使用的端口,请在输出中搜索与以下日志条目类似的行,特别是包含本示例中突出显示的 AH00072 错误代码的行:
Output-- Logs begin at Tue 2020-07-14 20:10:37 UTC, end at Tue 2020-07-28 14:01:40 UTC. -- . . . Jul 28 14:03:01 b06f9c91975d apachectl[71]: (98)Address already in use: AH00072: make_sock: could not bind to address [::]:80 Jul 28 14:03:01 b06f9c91975d apachectl[71]: (98)Address already in use: AH00072: make_sock: could not bind to address 0.0.0.0:80 Jul 28 14:03:01 b06f9c91975d apachectl[71]: no listening sockets available, shutting down
此输出指示两个 AH00072 错误。 其中第一个解释了 Apache 无法绑定到 [::]:80 地址,即所有可用 IPv6 接口上的端口 80。 下一行,地址为 0.0.0.0:80,表示 Apache 无法绑定到所有可用 IPv4 接口上的端口 80。 根据您的系统配置,IP 地址可能不同且仅显示单个 IP,并且可能仅包含 IPv4 或 IPv6 错误。
即使您自己的系统可能有不同的冲突接口和端口,错误也会与此处显示的输出类似。 通过 journalctl 的输出,您将能够在本教程的以下部分中使用 ss 诊断问题。
使用 ss 和 ps 实用程序进行故障排除
要解决 AH00072 错误,您需要确定其他进程正在侦听 Apache 尝试使用的 IP 地址和端口。 大多数现代 Linux 发行版都包含一个名为 ss 的实用程序,可用于收集有关系统网络套接字状态的信息。
在前面的 journalctl 部分中,某些内容已经绑定到端口 80 上的 IPv4 和 IPv6 地址。 以下命令将确定已绑定到端口 80 上的 IPv4 接口的进程的名称。 如果它与以下命令中的 80 不同,请确保从错误消息中替换端口:
sudo ss -4 -tlnp | grep 80
ss 命令的标志以下列方式改变其默认输出:
-4限制ss只显示 IPv4 相关的套接字信息。-t将输出限制为仅tcp套接字。-l显示考虑了-4和-t限制的所有侦听套接字。-n确保显示端口号,而不是像“httporhttps”这样的协议名称。 这很重要,因为 Apache 可能会尝试绑定到非标准端口,并且与实际端口号相反,服务名称可能会令人困惑。-p输出有关绑定到端口的进程的信息。
使用所有这些标志,您将收到如下输出:
OutputLISTEN 0 511 0.0.0.0:80 0.0.0.0:* users:(("nginx",pid=40,fd=6))
在排除 AH00072 错误时,前三个字段并不重要,因此可以忽略它们。 重要的字段是第四个 (0.0.0.0:80),它匹配您之前发现的 journalctl 错误,以及最后一个 users:(("nginx",pid=40,fd=6)),特别是 pid=40 部分.
如果您遇到与 IPv6 接口相关的 AH00072 错误,请重复 ss 调用,这次使用 -6 标志将接口限制为 IPv6 网络堆栈,如下所示:
sudo ss -6 -tlnp |grep 80
OutputLISTEN 0 511 [::]:80 [::]:* users:(("nginx",pid=40,fd=7))
如果与此处给出的突出显示的 80 不同,请再次从 journalctl 输出中替换有问题的端口号。
在 IPv4 和 IPv6 错误的这两种情况下,ss 输出表明有一个进程 ID 为 40 的程序(输出中的 pid=40)绑定到 [X174X ] 和 [::]:80 接口。 此过程阻止 Apache 启动,因为它已经拥有该端口。 要确定程序的名称,请像这样使用 ps 实用程序,用输出中的进程 ID 代替此示例中突出显示的 40 值:
sudo ps -p 40
您将收到类似于以下内容的输出:
OutputPID TTY TIME CMD 40 ? 00:00:00 nginx
输出中突出显示的 nginx 是正在侦听接口的进程的名称。 现在您有了阻止 Apache 启动的程序的名称,您可以决定如何解决该错误。 您可以停止 nginx 进程,重新配置 nginx 以侦听不同的接口和端口,或重新配置 Apache 以避免端口冲突。
请务必注意,如果您正在诊断 AH00072 错误,则该过程可能与 nginx 不同,并且端口和 IP 地址可能并不总是 0.0.0.0 或 [::]。 通常,不同的 Web 服务器和代理将在同一台服务器上使用。 每个都可能试图绑定到不同的 IPv4 端口和 IPv6 接口以处理不同的 Web 流量。 例如,配置了 HAProxy 的服务器在端口 8080 上侦听 IPv4 环回地址(也称为 localhost)将显示 ss 输出,如下所示:
OutputLISTEN 0 2000 127.0.0.1:8080 0.0.0.0:* users:(("haproxy",pid=545,fd=7))
将指示特定 IP 地址和端口的 systemctl 输出或 journalctl 输出与来自 ss 的诊断数据组合起来很重要,然后是 ps 以缩小范围关闭导致 Apache 无法启动的进程。
结论
在本教程中,您学习了如何对 IPv4 和 IPv6 接口上的 Apache AH00072 make_sock: could not bind to address 错误消息进行故障排除。 您学习了如何使用 systemctl 检查 Apache 服务器的状态并尝试查找错误消息。 您还学习了如何使用 journalctl 检查 systemd 日志以获取有关 AH00072 错误的特定信息。
通过日志中的相应错误消息,您随后了解了 ss 实用程序以及如何使用它来检查系统网络套接字的状态。 之后,您学习了如何将 ss 中的进程 ID 信息与 ps 实用程序结合起来,以查找导致 Apache 无法启动的进程的名称。