Lighttpdで全ページ503を返す

先日自宅サーバが起動しなくなってしまいました．10年以上ほぼ起動しっぱなしでしたししょうがないかなという感じも．この端末はNASやUnbound，apt-cacher-ngなど自宅向けのサービスの他にも外部向けのWebServerとしても動作させていました．
すぐに復旧するのは難しそうなのでとりあえずシングルボードコンピュータでWebServerを起動してHTTPステータスコードの503を返すようにしてみました．

利用したシングルボードコンピュータ

Raspberry Pi 3 model B (SoC arm v7 4core / Memory 1GB / OS Raspberry Pi OS bullseye armhf)

設定したいこと

2つのドメインのhttp/httpsへのアクセスにHTTPステータスコード503を返したい

前準備

すでに micro-httpd が動作しています．このアプリでやりたいことができるのかよくわからないのでこれは停止してLighttpdに変更します．

micro-httpdの停止と自動起動無効化

$ sudo systemctl stop micro-httpd
$ sudo systemctl disable micro-httpd

Note

もう使わないのであれば apt purge micro-httpd でいいと思います．

Lighttpdのインストール

Raspberry Pi OSパッケージのLighttpdを導入します．

Lighttpdのインストール

$ sudo apt install lighttpd

SSL証明書の入手

認証局には以前も利用していたLet’s Encryptを利用します．

Let’s Encrypt – フリーな SSL/TLS 証明書

専用の証明書管理ツールのcertbotを導入します．これもディストリビューションパッケージから導入します．

Certbot | Certbot

$ sudo apt install certbot

早速証明書を取得します．

$ sudo certbot certonly -d sub1.example.org (1)
Saving debug log to /var/log/letsencrypt/letsencrypt.log
How would you like to authenticate with the ACME CA?
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1: Spin up a temporary webserver (standalone)
2: Place files in webroot directory (webroot)
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Select the appropriate number [1-2] then [enter] (press 'c' to cancel): 2 (2)
Plugins selected: Authenticator webroot, Installer None
Requesting a certificate for sub1.example.com
Performing the following challenges:
http-01 challenge for sub1.example.org
Input the webroot for sub1.example.org: (Enter 'c' to cancel): /var/www/html (3)
:

sub1.example.org というドメインの証明書を取得

認証にLighttpdのhttpdを利用

Lighttpdのドキュメントルートを指定

同様にもう一つのドメインも設定します．

Lighttpdのhttps設定

lighttpd-enable-mod コマンドでLighttpdのsslモジュールとrewriteモジュールを有効にします．

$ sudo lighttpd-enable-mod rewrite ssl

Note

lighttpd-enable-mod は引数無しで実行すると対話形式になります．モジュールを無効にする場合は lighttpd-disable-mod コマンドが利用できます．

Lighttpdでのhttpsの設定

Lighttpdでhttpsでアクセスできるようにします．

lighttpd/conf-enabled/10-ssl.conf を編集します．

ssl.pemfile の行を以下のように書き換えてLet’s Encryptの証明書を使うようにします．

ssl.pemfile = "/etc/letsencrypt/live/sub1.example.org/fullchain.pem"
ssl.privkey = "/etc/letsencrypt/live/sub1.example.org/privkey.pem"

その下に2つ目ののドメインを設定します．

$HTTP["host"] =~ "sub2.example.org"{
ssl.pemfile = "/etc/letsencrypt/live/sub2.example.org/fullchain.pem"
ssl.privkey = "/etc/letsencrypt/live/sub2.example.org/privkey.pem"
}

Lighttpdを再読込して動作を確認します．

$ sudo systemctl lighttpd restart
$ w3m https://sub1.example.org/
$ w3m https://sub2.example.org/

HTTPステータスコード503を返すようにする

HTTPステータスコード503を返すだけのcgi scriptを作成していつもそれを返すようにします．

cgiを有効に

lighttpd-enable-mod コマンドでLighttpdのcgiモジュールを有効にします．

$ sudo lighttpd-enable-mod cgi

/etc/lighttpd/conf-enabled/10-cgi.conf を以下のように修正します．

$ grep -v ^# lighttpd/conf-enabled/10-cgi.conf | uniq

server.modules += ( "mod_cgi" )

cgi.assign = (
".cgi" => "/usr/bin/perl",
)

Lighttpdを再読込して動作を確認します．

$ sudo systemctl lighttpd restart
$ echo "#!/usr/bin/perl
print 'Content-Type: text/plain\n\nhello world.'" > /var/www/html/hello.cgi
$ sudo chown www-data.www-data /var/www/html/hello.cgi
$ sudo chmod 700 /var/www/html/hello.cgi
$ w3m https://sub1.example.org/hello.cgi
$ sudo rm /var/www/html/hello.cgi

503を返すcgiを用意

HTTPステータスコード503を返す /var/www/html/503.cgi を用意します．

#!/usr/bin/perl

use strict;
use warnings;

print "Status: 503 Service Unavailable\n";
print "Content-Type: text/html\n\n";
print <<END_OF_HTML;






home.matoken.org

code{white-space: pre-wrap;}
span.smallcaps{font-variant: small-caps;}
span.underline{text-decoration: underline;}
div.column{display: inline-block; vertical-align: top; width: 50%;}
div.hanging-indent{margin-left: 1.5em; text-indent: -1.5em;}
ul.task-list{list-style: none;}



Server is down.


END_OF_HTML

権限を設定して動作確認します．

$ sudo chown www-data.www-data /var/www/html/503.cgi
$ sudo chmod 700 /var/www/html/503.cgi
$ w3m -dump_head https://sub1.example.org/503.cgi | grep ^HTTP
HTTP/1.0 503 Service Unavailable
$ w3m https://sub1.example.org/503.cgi

Lighttpdですべてのアクセスに503を返すようにする

/etc/lighttpd/lighttpd.conf ファイルに以下を追記します．これですべてのURLが503.cgiになるはずです．

$HTTP["url"] != "/503.cgi$" {
url.rewrite = ( "" => "/503.cgi" )
}

Lighttpdを再読込して動作を確認します．

$ sudo systemctl lighttpd restart
$ w3m https://sub1.example.org/hoge
$ w3m https://sub2.example.org/fuga
$ w3m http://sub1.example.org/hoge
$ w3m http://sub2.example.org/fuga

環境

$ dpkg-query -W lighttpd certbot w3m perl
certbot 1.12.0-2
lighttpd 1.4.59-1+deb11u1
perl 5.32.1-4+deb11u2
w3m 0.5.3+git20210102-6
$ lsb_release -dr
Description: Raspbian GNU/Linux 11 (bullseye)
Release: 11
$ cat /proc/device-tree/model && echo
Raspberry Pi 3 Model B Rev 1.2