🌊

[SadServers] 解説 "Tokyo": can't serve web file

2022/11/04に公開

SadServersの問題の解説です。 URLは、https://sadservers.com/newserver/tokyo

SadServers って何? って人は、 SadServers解説 を見てください。
一言でいうと、LeetCode (コーディング問題集) の Linuxサーバ設定版のようなものです。

問題

Level: Medium

Description: There's a web server serving a file /var/www/html/index.html with content "hello sadserver" but when we try to check it locally with an HTTP client like curl 127.0.0.1:80, nothing is returned. This scenario is not about the particular web server configuration and you only need to have general knowledge about how web servers work.

コンテンツ "hello sadserver" を含むファイル /var/www/html/index.html を提供しているウェブサーバーがありますが、curl 127.0.0.1:80 のような HTTP クライアントでローカルにそれを確認しようとすると、何も返されません。このシナリオは、特定のWebサーバーの構成に関するものではないので、Webサーバーがどのように動作するかについての一般的な知識があれば大丈夫です。

Test: curl 127.0.0.1:80 should return: hello sadserver

curl 127.0.0.1:80 は、hello sadserver を返すはずです。

解き方

まず、 curl 127.0.0.1:80 を試します。 何も応答が無いので、Ctrl-C で止めます。

root@ip-172-31-21-14:/# curl 127.0.0.1:80
^C

ポート80でListenをしているのか、しているならば、どのプロセスかを確認するために lsofコマンドを使います。 -i:ポート番号 で、ポート番号を開いているプロセスを表示します。

root@ip-172-31-21-14:/# lsof -i:80
COMMAND PID     USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
apache2 630     root    4u  IPv6  17546      0t0  TCP *:http (LISTEN)
apache2 791 www-data    4u  IPv6  17546      0t0  TCP *:http (LISTEN)
apache2 792 www-data    4u  IPv6  17546      0t0  TCP *:http (LISTEN)

apache2がポート80でListenしていることがわかります。(ユーザはwww-data)

それなのに、なぜ、ポート80へのアクセスができないのでしょうか? ファイアウォールの設定を確認するために、iptableコマンドでチェックします。 -L オプションで現状の設定を確認できます。

root@ip-172-31-21-14:/# iptables -L
Chain INPUT (policy ACCEPT)
target     prot opt source               destination         
DROP       tcp  --  anywhere             anywhere             tcp dpt:http

Chain FORWARD (policy ACCEPT)
target     prot opt source               destination         

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination         

どうやら、入力される、Chain INPUTのDROPルールで、全TCPパケットがDROPしているようです。そのため、ポート80への通信が止められていたようです。 この設定をクリアします。 iptables -Fで設定をクリアします。 クリア後 -Lで再度確認します。

root@ip-172-31-21-14:/# iptables -F 
root@ip-172-31-21-14:/# iptables -L
Chain INPUT (policy ACCEPT)
target     prot opt source               destination         

Chain FORWARD (policy ACCEPT)
target     prot opt source               destination         

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination         

Chain INPUTの DROPルールがなくなっていることが確認できます。

さて、あらためて、curlを実行します。

root@ip-172-31-21-14:/# curl 127.0.0.1:80
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>403 Forbidden</title>
</head><body>
<h1>Forbidden</h1>
<p>You don't have permission to access this resource.</p>
<hr>
<address>Apache/2.4.52 (Ubuntu) Server at 127.0.0.1 Port 80</address>
</body></html>

通信はできました。ですが、hello sadserverではなく、何やらエラーとなっています。
どうやら、パーミッションが不正のようです。

問題に、Webサーバが返すファイルは /var/www/html/index.html とあるので、このファイルのパーミッションの確認をします。

root@ip-172-31-21-14:/# ls -l /var/www/html/index.html 
-rw------- 1 root root 16 Aug  1 00:40 index.html

rootのみが、rwできることがわかります。 apache2プロセスのwww-dataユーザで動作しているので、 /var/www/html/index.html にアクセスできないということです。

だれでも読めるように、chmod 644でパーミッションを変更します。

root@ip-172-31-21-14:/# chmod 644 /var/www/html/index.html 
# 確認
root@ip-172-31-21-14:/# ls -l /var/www/html/index.html 
-rw-r--r-- 1 root root 16 Aug  1 00:40 /var/www/html/index.html

あらためて、curlを実行

root@ip-172-31-21-14:/var/www/html# curl 127.0.0.1:80
hello sadserver

Discussion