SadServers
Linuxサーバ管理者向けのLeetCodeのようなもの
"Saint John": what is writing to this log file?
問題
/var/log/bad.log
にログが書き込みされ続けてディスクを圧迫するのでそれがされないようにしたい。
解法
lsof /var/log/bad.log
でファイルを対象としているプロセスがわかるのでそのプロセスをkillして終了。
$ lsof /var/log/bad.log
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
badlog.py 618 ubuntu 3w REG 259,1 10671 67701 /var/log/bad.log
$ kill -9 618
"Saskatoon": counting IPs.
問題
/home/admin/access.log
にwebサーバのアクセスログがある。このファイル中で最もアクセスが多かったIP元を/home/admin/highestip.txt
に記録したい。
解法
cut
でIP部分だけを抜き出し、sort
uniq
で重複しているIPを集計する。
uniq
は連続している重複を取り除くので前段にsort
が必要なことに注意。
cut -d " " -f 1
でスペース区切りの先頭カラムのみ取り出している。これはawk '{print $1}'
でもできる。
$ cat /home/admin/access.log | cut -d " " -f 1 | sort | uniq -c | sort | tail
82 198.46.149.143
83 208.115.111.72
84 100.43.83.137
99 68.180.224.225
102 209.85.238.199
113 50.16.19.13
273 75.97.9.59
357 130.237.218.86
364 46.105.14.53
482 66.249.73.135
$ echo "66.249.73.135" > /home/admin/highestip.txt
"Santiago": Find the secret combination
問題
次の2つの数字を見つけ出したい。
-
/home/admin
ディレクトリの*.txt
にあるAlice
が出現する行数 -
Alice
が1回しか出てこないファイルがある。そのAlice
が出現する次の行に書かれている数値
解法
# 指定のファイル内でAliceが出現する行数
$ grep Alice /home/admin/*.txt | wc -l
411
# Aliceが1回しか出てこないファイルを特定
$ grep -c Alice *.txt
11-0.txt:398
1342-0.txt:1
1661-0.txt:12
84-0.txt:0
# そのファイルでAliceが出てくる行と前後1行を表示
$ grep -1 Alice 1342-0.txt
PUBLISHER
Alice
156 CHARING CROSS ROAD
$ echo -n 411 > /home/admin/solution; echo 156 >> /home/admin/solution
"Manhattan": can't write data into database.
問題
PostgreSQLに行をインサートしようとしてもできなくなっているのでできるようにしたい。
解法
実際にINSERTを行いPostgreSQLのログを確認する。
No space left on device
とあるのでディスク空き容量が足りないことがわかる。
$ sudo -u postgres psql -c "insert into persons(name) values ('jane smith');" -d dt
psql: error: connection to server on socket "/var/run/postgresql/.s.PGSQL.5432" failed: No such file or directory
Is the server running locally and accepting connections on that socket?
# /var/log/syslogを見ても同様のエラーが出ていることがわかる
$ less /var/log/postgresql/postgresql-14-main.log.1
2023-01-08 05:15:39.112 UTC [646] FATAL: could not create lock file "postmaster.pid": No space left on device
pg_ctl: could not start server
Examine the log output.
df
コマンドでディスク使用量を確認すると/opt/pgdata
が100%使用されている。
$ 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
実際に/opt/pgdata
を確認するとバックアップファイルが大半を占めていることが確認できるので、削除してPostgreSQLを再起動する。
$ ls -lah /opt/pgdata
total 8.0G
drwxr-xr-x 3 postgres postgres 82 May 21 2022 .
drwxr-xr-x 3 root root 4.0K May 21 2022 ..
-rw-r--r-- 1 root root 69 May 21 2022 deleteme
-rw-r--r-- 1 root root 7.0G May 21 2022 file1.bk
-rw-r--r-- 1 root root 923M May 21 2022 file2.bk
-rw-r--r-- 1 root root 488K May 21 2022 file3.bk
drwx------ 19 postgres postgres 4.0K May 21 2022 main
$ rm /opt/pgdata/*.bk
$ systemctl restart postgresql
$ sudo -u postgres psql -c "insert into persons(name) values ('jane smith');" -d dt
INSERT 0 1
"Tokyo": can't serve web file
問題
hello sadserver
と書かれた/var/www/html/index.html
をwebサーバで配信しているがcurl 127.0.0.1:80
してもレスポンスが来ないので返ってくるようにしたい。
解法
試しにcurl
してみる。
# レスポンスが来ないことが確認できる
$ curl 127.0.0.1:80
# 80番をLISTENしているプロセスを確認するとapache2が動いていることがわかる
$ lsof -i:80
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
apache2 643 root 4u IPv6 16815 0t0 TCP *:http (LISTEN)
apache2 775 www-data 4u IPv6 16815 0t0 TCP *:http (LISTEN)
apache2 776 www-data 4u IPv6 16815 0t0 TCP *:http (LISTEN)
80番がブロックされているか確認。
INPUTで全ポートに対するDROPルールがあるためiptables -F
でクリアする。
$ 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
$ iptables -F
もう一度curl
すると権限がないと言われる。
$ 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>
ファイルの権限を見るとowner(root)にしか読み取り権限がないのでchmod 644
でその他ユーザーにも読み取り権限を与える。
root@ip-172-31-21-14:/# ls -la /var/www/html/index.html
-rw------- 1 root root 16 Aug 1 00:40 /var/www/html/index.html
root@ip-172-31-21-14:/# chmod 644 /var/www/html/index.html
root@ip-172-31-21-14:/# curl 127.0.0.1:80
hello sadserver
"Cape Town": Borked Nginx
問題
Nginxにcurl -I 127.0.0.1:80
としても次のようなエラーが出るのを直したい。
curl: (7) Failed to connect to localhost port 80: Connection refused
解法
nginxのステータスを確認。
/etc/nginx/sites-enabled/default
の1行目に;
があってエラーになっていることがわかるので削除。
$ 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 Mon 2023-01-09 13:01:25 UTC; 30s ago
Process: 581 ExecStartPre=/usr/sbin/nginx -t (code=exited, status=1/FAILURE)
CPU: 33ms
Jan 09 13:01:24 ip-172-31-34-5 systemd[1]: Starting The NGINX HTTP and reverse proxy server...
Jan 09 13:01:25 ip-172-31-34-5 nginx[581]: nginx: [emerg] unexpected ";" in /etc/nginx/sites-enabled/default:1
Jan 09 13:01:25 ip-172-31-34-5 nginx[581]: nginx: configuration file /etc/nginx/nginx.conf test failed
Jan 09 13:01:25 ip-172-31-34-5 systemd[1]: nginx.service: Control process exited, code=exited, status=1/FAILURE
Jan 09 13:01:25 ip-172-31-34-5 systemd[1]: nginx.service: Failed with result 'exit-code'.
Jan 09 13:01:25 ip-172-31-34-5 systemd[1]: Failed to start The NGINX HTTP and reverse proxy server.
再起動してcurlするも500エラー。
$ sudo systemctl restart nginx
$ curl -I 127.0.0.1:80
HTTP/1.1 500 Internal Server Error
エラーログを確認するとToo many open filesのエラーが出ている。
nginxは1プロセスで多くのアクセスを捌くのでファイルを開く数(ファイルディスクリプタ)が多くなるが多くなりすぎるとエラーになる。
$ less /var/log/nginx/error.log
2022/09/11 16:26:17 [crit] 5801#5801: accept4() failed (24: Too many open files)
2022/09/11 16:26:17 [crit] 5801#5801: *2 open() "/var/www/html/index.nginx-debian.html" failed (24: Too many open files), client: 127.0.0.1, server: _, request: "GET / HTTP/1.1", host: "localhost:80"
ファイルディスクリプタはnginxの設定(/etc/nginx/nginx.conf
など)のworker_rlimit_nofile
でも設定されることがあるが、今回はsystemd側で過度に低い値が設定されていたようなのでコメントアウトする。
$ 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]
nginxを再起動してcurlを確認。
$ 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.
$ sudo systemctl daemon-reload
$ sudo systemctl restart nginx
$ curl -I 127.0.0.1:80
HTTP/1.1 200 OK
続きはgithubで管理することにしました。