Apache 是我很常使用的 Web Server 之一,某一天我自己的 Telegram 告警機器人發出訊息說 網站無法連線。
初步已經排除是主機掛掉的問題,連入主機後,先確認一下 Apache 是不是正常運作。
systemctl status httpd
反正都已經運作不正常了,就手動再將它啟動一次
systemctl start httpd
卻得到無法啟動的錯誤
Job for httpd.service failed because the control process exited with error code. See "systemctl status httpd.service" and "journalctl -xe" for details.
竟然手動啟動也失敗了,決定好好地看一下到底是什麼原因。
systemctl status -l httpd
仔細地看看錯誤記錄的部份,好了解到底是什麼原因
May 01 08:15:12 e5d37e27ed25 systemd[1]: Starting The Apache HTTP Server... May 01 08:15:12 e5d37e27ed25 httpd[808]: AH00558: httpd: Could not reliably determine the server's fully qualified domain name, using 172.17.0.2. Set the 'ServerName' directive globally to suppress this message May 01 08:15:12 e5d37e27ed25 httpd[808]: (98)Address already in use: AH00072: make_sock: could not bind to address 0.0.0.0:443 May 01 08:15:12 e5d37e27ed25 httpd[808]: no listening sockets available, shutting down May 01 08:15:12 e5d37e27ed25 httpd[808]: AH00015: Unable to open logs May 01 08:15:12 e5d37e27ed25 systemd[1]: httpd.service: main process exited, code=exited, status=1/FAILURE May 01 08:15:12 e5d37e27ed25 systemd[1]: Failed to start The Apache HTTP Server. May 01 08:15:12 e5d37e27ed25 systemd[1]: Unit httpd.service entered failed state. May 01 08:15:12 e5d37e27ed25 systemd[1]: httpd.service failed.
從錯誤訊息的第 3-4 行,已足以說明 443 埠被佔用,所以才會導致無法啟動。根據以往經驗,這可能是有其他的程序佔用了 443 埠。
先檢查一下有沒有任何程序把 443 埠佔用住
ss -lnt
非常有趣的是,竟然完全有任何程序把 443 埠佔用,換言之,就是 443 埠並沒有處於監聽狀態。
總覺得以前工作經驗好像曾碰過類似情況,但細節實在是有點忘記。所以我決定從 Apache 的設定檔看起來。
先從 /etc/httpd/conf/ 看起,並沒有發現什麼異狀。
再往 /etc/httpd/conf.d/ 看起,突然覺得怪怪的。
根據 /etc/httpd/conf.d/README 內容提到,Apache 對於 /etc/httpd/conf.d/*.conf 的處理方式,會是依其檔名的順序做處理。也因此我個人在習慣上,會將檔名做一點改變,通常是加上「NN-」這樣的前綴,NN 指的則是兩位數字。一方面是確保其處理的順序,另一方面只是單純個人覺得在管理上的方便。
怪怪的部份,是因為我發現竟然有兩個關於 SSL 的設定檔。
突然覺得好像有點知道以前經驗的細節。先直上指令
find /etc/httpd/{conf,conf.d} -type f | xargs grep -Ei "^[\t ]*listen" -n
再看看結果為何
/etc/httpd/conf/httpd.conf:42:Listen 80 /etc/httpd/conf.d/00-ssl.conf:5:Listen 443 https /etc/httpd/conf.d/ssl.conf:5:Listen 443 https
從結果來看,這兩個 SSL 設定檔,都要起一個 443 埠,因為 00-ssl.conf 先起了 443 埠,接著 ssl.conf 又要起一個 443 埠,結果因為 ssl.conf 無法起 443 埠,而導致之前的錯誤。
方向已經確定了,為保險起見,我將 ssl.conf 先改名為 ssl.conf.bak,再試著啟動 Apache,似乎沒有出現什麼錯誤,再檢查一下運作狀態。
看來一切正常了!
結論
如果遇到 Apache 的 AH00072 錯誤,也就是錯誤訊息類似如下:
Address already in use: AH00072: make_sock: could not bind to address...
那麼解決方案如下:
- 檢查有沒有其他程序佔用特定的 IP 或 Listen Port
- 檢查 Apache 的設定檔有沒重複宣告 IP 或 Listen Port