💥

SadServers解説#14 "Cape Town":Borked Nginx

2024/05/08に公開

https://ja.wikipedia.org/wiki/ケープタウン

問題概要

シナリオ

故障したNginx

問題詳細

Nginxウェブサーバーがsystemdでインストールされて管理されています。curl -I 127.0.0.1:80を実行すると、curl: (7) Failed to connect to localhost port 80: Connection refusedと表示されます。デフォルトのNginxページを取得できるように修正してください。

解決判定

Check My Solutionボタンをクリックしてください。

解答が正解かどうか、コマンドプロンプト上で確認することも可能です。以下と同じ出力が得られた場合は正解です。

$ curl -Is 127.0.0.1:80 | head -1
HTTP/1.1 200 OK

 

問題解決の方針

【表示する】

今回の問題では、通信が通らない原因を切り分ける力が求められています。
通信が通らない理由として、以下が考えられますね。

  1. HTTPクライアントが正常に起動していない
  2. HTTPクライアントは正常に起動しているが、通信が遮断されている

今回は、上のような想定で、原因を切り分けていきましょう。

解決の手順を表示する
  1. Nginxが問題なく起動しているか確認する
  2. 起動に問題がある場合は、エラーメッセージに従って対処し、Nginxを再起動します。
  3. Nginxが起動できるようになっても問題が解決しない場合は、ログを見て対処します。

 

ヒント

一部、SadServers公式のヒントを改変しています。

ヒント1

まずは、WEBサーバであるNginxが正常に稼働しているか確認します。

実行コマンド
$ systemctl status nginx
● nginx.service - The NGINX HTTP and reverse proxy server
     Loaded: loaded (/etc/systemd/system/nginx.service; enabled; vendor preset: enabled)
     Active: failed (Result: exit-code) since Wed 2024-05-08 11:45:54 UTC; 49s ago
    Process: 576 ExecStartPre=/usr/sbin/nginx -t (code=exited, status=1/FAILURE)
        CPU: 31ms

May 08 11:45:54 i-00bccd7ede4ef3a45 systemd[1]: Starting The NGINX HTTP and reverse proxy server...
May 08 11:45:54 i-00bccd7ede4ef3a45 nginx[576]: nginx: [emerg] unexpected ";" in /etc/nginx/sites-enabled/default:1
May 08 11:45:54 i-00bccd7ede4ef3a45 nginx[576]: nginx: configuration file /etc/nginx/nginx.conf test failed
May 08 11:45:54 i-00bccd7ede4ef3a45 systemd[1]: nginx.service: Control process exited, code=exited, status=1/FAILURE
May 08 11:45:54 i-00bccd7ede4ef3a45 systemd[1]: nginx.service: Failed with result 'exit-code'.
May 08 11:45:54 i-00bccd7ede4ef3a45 systemd[1]: Failed to start The NGINX HTTP and reverse proxy server.

どうやら、/etc/nginx/sites-enabled/defaultというファイルにて、予期しない;があるようです。要は、設定ファイルの構文エラーですね。
プログラムのデバッグをしたことがある人は、幾度となく目にしたエラーメッセージだと思います…。

ヒント2

/etc/nginx/sites-enabled/defaultというファイルにて、予期しない;があるようなので、ファイルの内容を確認し、構文エラーを修正しましょう。

実行コマンド1
$ sudo less /etc/nginx/sites-enabled/default
;
##
# You should look at the following URL's in order to grasp a solid understanding
# of Nginx configuration files in order to fully unleash the power of Nginx.

どうやら、設定ファイルの1行目に、不要な;が入ってしまっているようです。
念のため、変更を復元できるようにバックアップを取ってから修正しましょう。

実行コマンド2
$ sudo cp /etc/nginx/sites-enabled/default /tmp/default.bak
$ sudo vi /etc/nginx/sites-enabled/default
一行目をコメントアウト
$ sudo diff /etc/nginx/sites-enabled/default /tmp/default.bak
1c1
< # ;
---
> ;

意図通りに設定ファイルを編集できたことが確認出来たら、Nginxを再起動してみましょう。

ヒント3

設定ファイルを変更したので、Nginxを再起動してみます。

$ sudo systemctl restart nginx
$ systemctl status nginx
● nginx.service - The NGINX HTTP and reverse proxy server
     Loaded: loaded (/etc/systemd/system/nginx.service; enabled; vendor preset: enabled)
     Active: active (running) since Wed 2024-05-08 11:53:41 UTC; 7s ago
    Process: 923 ExecStartPre=/usr/sbin/nginx -t (code=exited, status=0/SUCCESS)
    Process: 924 ExecStart=/usr/sbin/nginx (code=exited, status=0/SUCCESS)
   Main PID: 925 (nginx)
      Tasks: 2 (limit: 524)
     Memory: 2.4M
        CPU: 51ms
     CGroup: /system.slice/nginx.service
             ├─925 nginx: master process /usr/sbin/nginx
             └─926 nginx: worker process

May 08 11:53:41 i-00bccd7ede4ef3a45 systemd[1]: Starting The NGINX HTTP and reverse proxy server...
May 08 11:53:41 i-00bccd7ede4ef3a45 nginx[923]: nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
May 08 11:53:41 i-00bccd7ede4ef3a45 nginx[923]: nginx: configuration file /etc/nginx/nginx.conf test is successful
May 08 11:53:41 i-00bccd7ede4ef3a45 systemd[1]: Started The NGINX HTTP and reverse proxy server.
$ 
$ curl -I 127.0.0.1:80 | head -1

起動はうまくいっているようですが、curlコマンドを実行したところ、500 Internal Server Errorが発生しているようです。ステータスコード500は、Internal(内部)の名前の通り、サーバ内で問題が発生していることによるエラーです。
起動時にエラーは出ていないようなので、ログファイルを探してログを見てみましょう。

実行コマンド

/var/log/messagejournalctlを見てみましたが、参考になるログは出力されていないようです。Nginxのログを見てみましょう。

$ sudo find /var/log -name nginx
/var/log/nginx
$ ls -la /var/log/nginx
total 234260
drwxr-xr-x 2 root     adm       4096 Sep 11  2022 .
drwxr-xr-x 9 root     root      4096 May  8 11:45 ..
-rw-r----- 1 www-data adm  239657448 May  8 11:58 access.log
-rw-r----- 1 www-data adm     209425 May  8 11:58 error.log
$ less /var/log/nginx/access.log 
$ less /var/log/nginx/error.log

/var/log/nginx/error.logに気になるエラーが出ていました。

/var/log/nginx/error.log
2024/05/08 13:17:15 [alert] 898#898: socketpair() failed while spawning "worker process" (24: Too many open files)
2024/05/08 13:17:15 [emerg] 899#899: eventfd() failed (24: Too many open files)
2024/05/08 13:17:15 [alert] 899#899: socketpair() failed (24: Too many open files)

Too many open filesということで、開いているファイルが多すぎるとのことです。

ヒント4

Nginxのサービスが開くことのできるファイル数の上限を増やしましょう。
Nginxサービスの設定はどこで行われているでしょうか。

実行コマンド

systemdにサービスを登録するためには、管理者用のユニットファイル管理フォルダである/etc/systemd/systemにユニットファイルを配置する必要があります。
ユニットファイルの設定を見てみましょう。

$ cat /etc/systemd/system/nginx.service 
[Unit]
Description=The NGINX HTTP and reverse proxy server
After=syslog.target network-online.target remote-fs.target nss-lookup.target
Wants=network-online.target

[Service]
Type=forking
PIDFile=/run/nginx.pid
ExecStartPre=/usr/sbin/nginx -t
ExecStart=/usr/sbin/nginx
ExecReload=/usr/sbin/nginx -s reload
ExecStop=/bin/kill -s QUIT $MAINPID
PrivateTmp=true
LimitNOFILE=10

[Install]
WantedBy=multi-user.target

LimitNOFILEの値が10になっています。この数字を増やせば良さそうです。
なお、LimitNOFILEとは、Limit Number of File Descriptors(ファイル記述子の数の制限)の略のようです。

実行コマンド

nginx.serviceのLimitNOFILEの値を10から100に変更してみます。
ユニットファイルを変更した際は、systemctl daemon-reloadコマンドで変更を反映することを忘れないようにしましょう。

$ sudo cp /etc/systemd/system/nginx.service /root/nginx.service.bak
$ sudo vi /etc/systemd/system/nginx.service
$ diff /etc/systemd/system/nginx.service /root/ngi
diff: /root/ngi: Permission denied
$ sudo diff /etc/systemd/system/nginx.service /root/nginx.service.bak
14c14
< LimitNOFILE=100
---
> LimitNOFILE=10
$
$ sudo systemctl daemon-reload
$ sudo systemctl restart nginx
$
$ curl -I 127.0.0.1:80 | head -1
HTTP/1.1 200 OK

ユニットファイルの設定値を変更し、再起動することで、無事にNginxがWEBサーバとして動作するようになりました!

ちなみに、systemctl daemon-reloadをしないままsystemctl restart nginxを実行しようとすると、ちゃんとsystemctl daemon-reloadをしろと怒られます。

$ sudo systemctl restart nginx
Warning: The unit file, source configuration file or drop-ins of nginx.service changed on disk. Run 'systemctl daemon-reload' to reload units.

 
「いきなり問題を解き始めても調べるばかりになってしまう…」 「やりたいことが分かっても、コマンドが分からない…」 という方は、下記の記事でLinuxのコマンドを復習してから、SadServersの問題に取り掛かってみてはいかがでしょうか。
https://zenn.dev/comf_nakamura/articles/linux_command

問題一覧はこちら

https://zenn.dev/comf_nakamura/articles/sadservers_sitemap

Discussion