これは何?
Linuxサーバのトラブルシューティング問題集 SadServers の解法メモ。
使用したコマンドなどについて書き残します。
完全にネタバレなので問題を見ていない人はブラウザバックを推奨します。
Linux初学者なのでところどころ理解が怪しい部分などがあります。ご指摘歓迎です。
1. what is writing to this log file?
ログに書き込み続けているプロセスを特定し、killコマンドで終了する。
ps
プロセス一覧の表示。
ps auxfやps -efで確認するのが主流らしい。
ps auxfの方が情報量が多いが、ps -ef はPPID(親プロセスID)を表示できる。
lsof
ファイルを開いているプロセスを確認できる。
ubuntu@ip-172-31-32-108:/$ lsof /var/log/bad.log
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
badlog.py 632 ubuntu 3w REG 259,1 19541 67701 /var/log/bad.log
さらにプロセスIDを指定することで、cwdなどが調べられる。
ubuntu@ip-172-31-32-108:/$ lsof -p 632
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
badlog.py 632 ubuntu cwd DIR 259,1 4096 258156 /home/ubuntu
...
3. counting IPs
ファイル内で登場頻度が一番多い単語を特定する。
awk
スペースやタブで区切られた文字列の、1つ目の要素を取り出す
awk '{print $1}'
Fオプションで区切り文字を指定可能
awk -F'[:]' '{print $1}'
uniq -c
各要素を出現回数と一緒に表示できる
482 66.249.73.135
364 46.105.14.53
357 130.237.218.86
273 75.97.9.59
113 50.16.19.13
4. can't serve web file
ファイアウォールの修正。
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
設定を確認すると、httpのINPUTをすべてDROP(パケットを破棄)する設定になっている。
また、Chain INPUT (policy ACCEPT)とあることから、ルールが指定されていないパケットについては一律でACCEPT(パケットを許可)する状態。
このため、当該設定を削除すれば良い。
root@ip-172-31-21-14:/# iptables -D INPUT 1
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の設定をpolicy DROPに変更して問題を解いてみる。
root@ip-172-31-21-14:/# iptables -P INPUT DROP
コマンドを打った瞬間プロンプトが動かなくなった。
policy DROPにしたのでこの瞬間にサーバーへの接続が弾かれてしまったらしい(それはそう)。
policyをDROPに変更するときは先にACCEPTの設定を行わないといけない。
ACCEPTにSSHとか入れればpolicy DROPにしても動くのでは…?と考えたが、これ以上リトライして問題サーバを起動するのは無作法なので、一旦ここまで。
5. can't write data into database.
PostgreSQLが立ち上がらないエラーの解消。
df
ディスクの空き領域のサイズを表示する。(disk freeの略)
root@ip-172-31-46-78:/# df -h
Filesystem Size Used Avail Use% Mounted on
udev 224M 0 224M 0% /dev
tmpfs 47M 1.5M 46M 4% /run
/dev/nvme1n1p1 7.7G 1.2G 6.1G 17% /
tmpfs 233M 0 233M 0% /dev/shm
tmpfs 5.0M 0 5.0M 0% /run/lock
tmpfs 233M 0 233M 0% /sys/fs/cgroup
/dev/nvme1n1p15 124M 278K 124M 1% /boot/efi
/dev/nvme0n1 8.0G 8.0G 28K 100% /opt/pgdata
さらにlsコマンドで/opt/pgdataを見ると、7GBのバックアップファイルが幅を利かせている。
root@ip-172-31-46-78:/# ls -lh /opt/pgdata
total 8.0G
-rw-r--r-- 1 root root 69 May 21 22:20 deleteme
-rw-r--r-- 1 root root 7.0G May 21 22:06 file1.bk
-rw-r--r-- 1 root root 923M May 21 22:17 file2.bk
-rw-r--r-- 1 root root 488K May 21 22:23 file3.bk
drwx------ 19 postgres postgres 4.0K May 21 22:24 main
これを削除して再起動する。
問題文からbkファイルの要不要は判断できないけれど、ディレクトリ一番上のファイルにdeletemeと書いてあるので消して良い。
6. Borked Nginx
/etc/systemd/system配下にあるnginxの設定ファイルを修正する。
7. Docker container won't start.
Dockerfileの修正。
ポート8888でexposeをする必要があるが、8888は既に別のアプリが使っている。ポートを使用しているプロセスを特定して削除する。
netstat
ホストのネットワーク接続状態を確認できる。
pオプションをつけるとそれぞれの接続を使っているプロセスが表示できる。
admin@ip-172-31-41-254:~/app$ sudo netstat -pa | grep 8888
tcp 0 0 0.0.0.0:8888 0.0.0.0:* LISTEN 617/nginx: master p
tcp6 0 0 [::]:8888 [::]:* LISTEN 617/nginx: master p
8. it's always DNS.
/etc/nsswitch.confで名前解決の設定を修正する。
(DNS周りのエラーなのでresolv.confに問題があるのか…?と色々調べていたが不正解。そもそもDNSサーバに問い合わせができていないので見当違いだった)
9. Docker web container can't connect to db container.
WORDPRESS_DB_HOSTがデフォルト値の'mysql'のままになっているので、これを修正する。
inspectでIPAddressを確認。
admin@ip-172-31-19-232:/$ sudo docker inspect mariadb | grep IPAddress
"SecondaryIPAddresses": null,
"IPAddress": "172.17.0.2",
"IPAddress": "172.17.0.2",
mariadbコンテナは3306番ポートをexposeしているので、このIPアドレスを指定すればDBへの接続ができる。
ここからどう対処するか考える。
wp-config.phpには
define( 'DB_HOST', getenv_docker('WORDPRESS_DB_HOST', 'mysql') );
とあるので、以下のように環境変数WORDPRESS_DB_HOSTを追加してコンテナを再起動すれば、コンテナ間の通信は通るようになる。
admin@ip-172-31-19-232:/$ sudo docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
6ffb084b515c wordpress:sad "docker-entrypoint.s…" 3 months ago Up 3 minutes 0.0.0.0:80->80/tcp wordpress
0eef97284c44 mariadb:latest "docker-entrypoint.s…" 3 months ago Up 3 minutes 0.0.0.0:3306->3306/tcp mariadb
admin@ip-172-31-19-232:/$ sudo docker rm -f 6ffb084b515c
6ffb084b515c
admin@ip-172-31-19-232:/$ sudo docker run -d -e WORDPRESS_DB_HOST=172.17.0.1 --name wordpress -p 80:80 wordpress:sad
e38fcd8eae5b629898d8d72b7ef539669d7bf60098f958e2a31573e74bef5659
admin@ip-172-31-19-232:/$ sudo docker exec wordpress env | grep WORDPRESS_DB_
WORDPRESS_DB_HOST=172.17.0.2
WORDPRESS_DB_PASSWORD=password
WORDPRESS_DB_USER=root
しかし、この設問は以下のテストが通ることを要求している。
Test:
sudo docker exec wordpress mysqladmin -h mysql -u root -ppassword ping
. The wordpress container is able to connect to the database in the mariadb container and returnsmysqld is alive
.
テストでホスト名に -h mysql を指定しているので、このままではテストが通らない。
これを通すために、/etc/hostsに一行追加する。
admin@ip-172-31-19-232:/$ sudo docker exec -ti wordpress bash
root@da9ad9f3ad05:/var/www/html# echo "172.17.0.1 mysql" >> /etc/hosts
これでテストも通る。
admin@ip-172-31-19-232:/$ sudo docker exec wordpress mysqladmin -h mysql -u root -ppassword ping
mysqld is alive
10. Docker and Kubernetes web app not working.
ImagePullBackOffでPodが立ち上がらない状態なので、プライベートのDocker Registryにイメージをpushする。
また、curl localhost:8888
のリクエストを成功させるためにPodのポートフォワーディングを行う必要がある。
admin@ip-10-0-0-64:~$ kubectl port-forward deployments/webapp-deployment 8888 -n web
Forwarding from 127.0.0.1:8888 -> 8888
Forwarding from [::1]:8888 -> 8888
11. WTFIT – What The Fun Is This?
wtfitという名前の謎のファイルがあるので、どうにか実行できるようにする。
(CTFチックな問題だ)
admin@ip-172-31-36-138:~$ file wtfit
wtfit: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), statically linked, Go BuildID=_iHDgQr9_DkcDPzFkdEV/KeopbEbY41Cs4Jx-plaD/bLd_UQ3kiokG80g9hhbY/qtKkikMAZmQbLl9qoMCF, not stripped
とりあえず実行可能ファイルではあるらしい。
admin@ip-172-31-36-138:~$ ls -l
total 6236
drwxr-xr-x 2 admin admin 4096 Sep 13 18:18 agent
-rw-r--r-- 1 admin admin 6381234 Sep 13 18:17 wtfit
実行権限がないのでchmodする。
admin@ip-172-31-36-138:~$ chmod 755 wtfit
bash: /usr/bin/chmod: Permission denied
ええ…
chmodをカレントディレクトリにinstallする。
admin@ip-172-31-36-138:~$ install -m 755 /usr/bin/chmod .
admin@ip-172-31-36-138:~$ ./chmod 755 wtfit
admin@ip-172-31-36-138:~$ ls -l
total 6300
drwxr-xr-x 2 admin admin 4096 Sep 13 18:18 agent
-rwxr-xr-x 1 admin admin 64448 Nov 6 16:57 chmod
-rwxr-xr-x 1 admin admin 6381234 Sep 13 18:17 wtfit
chmodできた。
再実行。
admin@ip-172-31-32-154:~$ /home/admin/wtfit
ERROR: can't open config file
config fileが開けないとだけ出力されている。
straceで再確認。
admin@ip-172-31-36-138:~$ strace /home/admin/wtfit
...
openat(AT_FDCWD, "/home/admin/wtfitconfig.conf", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
write(1, "ERROR: can't open config file\n", 30ERROR: can't open config file
) = 30
exit_group(1) = ?
+++ exited with 1 +++
wtfitconfig.confを開こうとしているが、ファイルが存在していない。
空ファイルを作成して再実行。
admin@ip-172-31-36-138:~$ touch /home/admin/wtfitconfig.conf
admin@ip-172-31-36-138:~$ /home/admin/wtfit
ERROR: can't connect to server
サーバーに接続できないらしい。
tcpdump -i loを実行し、自分自身へのパケットをキャプチャする。
admin@ip-172-31-36-138:~$ sudo tcpdump -i lo
tcpdump: verbose output suppressed, use -v[v]... for full protocol decode
listening on lo, link-type EN10MB (Ethernet), snapshot length 262144 bytes
17:05:12.868414 IP localhost.34996 > localhost.7777: Flags [S], seq 534663709, win 65495, options [mss 65495,sackOK,TS val 383227227 ecr 0,nop,wscale 6], length 0
17:05:12.868426 IP localhost.7777 > localhost.34996: Flags [R.], seq 0, ack 534663710, win 0, length 0
17:05:12.868414 IP localhost.34996 > localhost.7777: Flags [S], seq 534663709, win 65495, options [mss 65495,sackOK,TS val 383227227 ecr 0,nop,wscale 6], length 0
17:05:12.868425 IP localhost.7777 > localhost.34996: Flags [R.], seq 0, ack 534663710, win 0, length 0
ポート7777に何らかのリクエストを送っている。
問題文に書いてあった wtfit needing to communicate to a service in order to start
の処理らしい。
ポート7777で適当なサーバーを立ち上げる。
admin@ip-172-31-36-138:/$ python3 -m http.server 7777
Serving HTTP on 0.0.0.0 port 7777 (http://0.0.0.0:7777/) ...
admin@ip-172-31-36-138:/$ /home/admin/wtfit
OK.
何がOKなのかはよく分からないけれど、題意は満たせたらしい。
12. can't write data into database.
/etc/fstab
マウントするファイルシステムを管理するファイル。
# /etc/fstab: static file system information
UUID=5db68868-2d70-449f-8b1d-f3c769ec01c7 / ext4 rw,discard,errors=remount-ro,x-systemd.growfs 0 1
UUID=72C9-F191 /boot/efi vfat defaults 0 0
/dev/xvdb /opt/pgdata xfs defaults,nofail 0 0
この設定だと「/dev/xvdb」デバイスを「/opt/pgdata」ディレクトリにマウントする。
root@ip-172-31-25-11:/# lsblk -f
NAME FSTYPE LABEL UUID FSAVAIL FSUSE% MOUNTPOINT
nvme0n1 xfs 9a2e1bf9-50e8-41a9-9f8c-5dd837869c50
nvme1n1
├─nvme1n1p1 ext4 5db68868-2d70-449f-8b1d-f3c769ec01c7 6G 16% /
├─nvme1n1p14
└─nvme1n1p15 vfat 72C9-F191 123.5M 0% /boot/efi
lsblkでnvme0n1がunmountになっていることが分かるので、「/dev/xvdb」を「/dev/nvme0n1」に書き換えてsystemctl daemon-reloadで設定を反映する。