メニュー 蕭寥亭 検索

自宅サーバ

14. Raspberry Pi 3 + スマホ対応への道 + その他

 前回のサーバ更新から3年が経ち、そろそろ、またやっとくかと思いまして。

 他の用途で使っていた Raspberry Pi 3 Model B( + ではない方です)が余っていたので、この機会に置き換えました。そこで旧サーバ機の Raspberry Pi 1 Model B+ とちょっとした比較をしてみましたので、ここでご紹介。

 最初はハードを置き換えるだけでサラッと済ませるつもりだったのですが、作業を進めていくうちにそうもいかない事情がでてきまして、おおごとになってしまいました。そのへんも少し書いておきますので、なにかのご参考になれば。

1.Raspberry Pi : 1 対 3 比較

 Raspberry Pi 各モデルの性能諸元の確認・比較はこちらが便利。

 旧サーバ機の Raspberry Pi 1 Model B+ の方は 前回更新時 から apt によるパッケージ更新はもちろん行っていますが、ソフトウェア構成はほぼ同じで、置き換え直前の状態でテストしています。

 新サーバ機の Raspberry Pi 3 Model B は、OSに以前 Raspbian という名称だった Raspberry Pi OS の Lite の最新版を使っています。バージョンやサイトの作りに違いはありますが、ソフトウェア構成は旧サーバ機とほぼ同じです。

① 消費電力比較

 まずは サンワサプライの簡易検電器・TAP-TST8 ワットモニター を使ってそれぞれの消費電力を計測したところ、結果は以下のとおりでした。

1 3
起動時最大 2.3W 2.8W
起動後安定状態 1.7〜1.8W 1.7〜1.8W

 起動時最大の消費電力こそ 3 が 0.5W ほど高いということになりましたが、その後の安定状態(外部からリクエスト等の負荷が基本的にかかっていない状態)では差がないということでした。3 はかなり性能が向上しているだけに、これはやや意外でした。

 おもしろいのは 1 を 6年前に計測した時 より今回の方が消費電力が下がっていることです。当時はサイト用に Ruby を使っていたのですが、その後、Go 言語に替えたことが効いているようです。もっとも ウチのサイトの構成って、かなり特殊 なので、よそでも同様の結果が出るかは疑問ですが。

② ApacheBench 比較

 恒例の Apache Bench による負荷テストです。 ff1100 のときRuby + Phusion Passenger + Nginx + Sinatra のとき と同様、リクエスト数を100、同時接続数を10、 サイトのトップページをリクエスト先にして測定しました。

 1 の結果は以下のとおり。

$ ab -n 100 -c 10 https://gok.dip.jp/index2.htm
This is ApacheBench, Version 2.3 <$Revision: 1843412 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/

							
Benchmarking gok.dip.jp (be patient).....done

							

							
Server Software:
Server Hostname:        gok.dip.jp
Server Port:            443
SSL/TLS Protocol:       TLSv1.2,ECDHE-RSA-CHACHA20-POLY1305,2048,256
Server Temp Key:        X25519 253 bits
TLS Server Name:        gok.dip.jp

							
Document Path:          /index2.htm
Document Length:        11022 bytes

							
Concurrency Level:      10
Time taken for tests:   27.858 seconds
Complete requests:      100
Failed requests:        0
Total transferred:      1159500 bytes
HTML transferred:       1102200 bytes
Requests per second:    3.59 [#/sec] (mean)
Time per request:       2785.846 [ms] (mean)
Time per request:       278.585 [ms] (mean, across all concurrent requests)
Transfer rate:          40.65 [Kbytes/sec] received

							
Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:      235 2228 248.1   2249    2635
Processing:   193  427 196.1    347    1142
Waiting:        9  152  44.9    153     366
Total:        535 2655 319.3   2619    3498

							
Percentage of the requests served within a certain time (ms)
  50%   2619
  66%   2670
  75%   2769
  80%   2836
  90%   3023
  95%   3211
  98%   3314
  99%   3498
 100%   3498 (longest request)

 赤字部分が所要時間です。27.858秒と SSL/TLS 対応前 の 2.270秒と比べると10倍以上かかってしまい、大幅に遅くなっています。

 一方、3 の結果はこちら。

$ ab -n 100 -c 10 https://gok.0j0.jp/index2.htm
This is ApacheBench, Version 2.3 <$Revision: 1843412 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/

							
Benchmarking gok.0j0.jp (be patient).....done

							

							
Server Software:
Server Hostname:        gok.0j0.jp
Server Port:            443
SSL/TLS Protocol:       TLSv1.2,ECDHE-RSA-CHACHA20-POLY1305,2048,256
Server Temp Key:        X25519 253 bits
TLS Server Name:        gok.0j0.jp

							
Document Path:          /index2.htm
Document Length:        12475 bytes

							
Concurrency Level:      10
Time taken for tests:   4.549 seconds
Complete requests:      100
Failed requests:        0
Total transferred:      1305800 bytes
HTML transferred:       1247500 bytes
Requests per second:    21.98 [#/sec] (mean)
Time per request:       454.943 [ms] (mean)
Time per request:       45.494 [ms] (mean, across all concurrent requests)
Transfer rate:          280.30 [Kbytes/sec] received

							
Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:      129  344  59.9    349     462
Processing:    36   84  32.5     79     183
Waiting:        4   24   9.6     24      50
Total:        180  428  64.5    430     573

							
Percentage of the requests served within a certain time (ms)
  50%    430
  66%    451
  75%    468
  80%    476
  90%    514
  95%    530
  98%    547
  99%    573
 100%    573 (longest request)

 おお、さすがに速くなっています。4.549秒で 1 の二割以下の時間で終了しています。すばらしい。

 目測ですが、テスト中、ウェブサーバのプロセスのCPU使用率は瞬間最大で、1 の場合が 90% 超、3 の場合が 280% 超(コアが4つあるので、同時に複数のコアが使われれば 100% 以上になる場合があります)となっていました。動作周波数の向上とコア数の増加の恩恵が受けられているようです。

③ CPU温度比較

 3 は 1 よりCPUの発熱量が高くなっている、ということだったので念のため、ヒートシンクを着けています(下の写真)。ちなみに 1 は素のままです。

ヒートシンクを着けた Raspberry Pi 3 Model B

 どちらも次のコマンドでその時点でのCPU温度を測ることができます。

$ vcgencmd measure_temp

 このコマンドを使って、2021年6月24〜28日の5日間、14時に両方のCPU温度を測ってみました。ついでに設置場所の室温も同日同時刻で測ってみました。結果は以下のとおり。

室温 1 3
6/24 27.7℃ 46.5℃ 50.5℃
6/25 27.6℃ 46.5℃ 51.0℃
6/26 28.7℃ 47.1℃ 52.1℃
6/27 29.2℃ 47.1℃ 52.6℃
6/28 28.9℃ 47.1℃ 52.1℃
平均 28.42℃ 46.86℃ 51.66℃

 ヒートシンク着けていても、やはり 3 の方が高いです。1 は今、実運用を外れている状態なので低めに出ているのかもしれませんが、平均で 5℃近く差があります。

 室温と 3 では平均で 23℃少々差があります。今までの 1 での運用記録から、室温の季節変化によりやはりCPU温度も上下することがわかっています。設置場所にはクーラー入れてないので、1 は実運用中の去年8月に 53℃まで上がったことがあります(逆に冬場は 30℃を切ります)。

 Raspberry Pi のサイトの文書によりますと、85°Cを上限と設定しているとのことです。

 85°Cなら、3 でもまだ余裕ありそうです。ヒートシンク着けていなかったら、どうだったかはわかりませんが。仮に屋外、直射日光があたるようなところに置くとしたら・・・、対策、必要ですね。

2.スマホ対応

 今や、インターネットの利用環境はスマホが中心になっています。

 ウチのサイトにいらっしゃる希少な利用者の方々のアクセス状況を確認しても、それははっきりとうかがえます。

 また、こんな話もあります。

 わたし自身はモバイルでウェブサイトの閲覧はあまりしないので(ウェブは専ら自宅で見て、外出時はほとんど見ない)、対応を怠ってきましたが、それもそろそろ限界、ということらしいです。よって、今回、サーバ更新に合わせてスマホ対応を実施しました。

 更新前の当サイトを画面狭めのスマホで閲覧すると、下の画像のように表示されたと思います。

更新前の当サイトを画面狭めのスマホで表示

 表示はとりあえずできるわけですが、一見して見づらいですね。具体的には

  • 字が小さくて読めない
  • 画像も小さい
  • リンク・ボタン等も小さくて指で押しづらい
  • 全体に縮小されて表示領域が狭くなっているのに、両サイドに無駄な余白がある
  • 画面の縦横比に構成が合ってない

といった問題点があります。これらをスマホの狭い画面でも適切に表示できるよう、修正しました。さらに

  • 表示面積を食うメニュー・検索はボタンで表示/非表示を切替
  • ページが縦長になりがちなので、上に戻るボタンを常時使用可能にする

等の修正を加え、まずモバイル機器向けの画面デザインを固めました。

 その上で、モバイル機器向けの画面デザインに最低限の変更を施して、PC向けを作りました。当サイトはブラウザの画面サイズにより、同じページの表示を切り替える、いわゆるレスポンシブウェブデザインを採用しています。

 Bootstrap 等の CSS フレームワークは使用しておらず、画面サイズが 768px 以上か未満か、の2パターンの切り替えだけで、この両者の間には画面サイズの違いに対応するためのデザイン上の最低限の差異があるのみです。記事内容が違っているとかいったことは基本ありません。

 PC向け(画面サイズ 768px 以上)の画面は、下の画像のような表示になります。

PC向け(画面サイズ 768px 以上)の画面

 モバイル機器向け(画面サイズ 768px 未満)の画面は、下の画像のような表示になります。

モバイル機器向け(画面サイズ 768px 未満)の画面

3.URL変更

 当サイトは DDNS を使ってサイトを公開しています。

 公開以来、ieServer.Net の無料サービスを使っていました。ずっと使い続けるつもりだったのですが、今回の更新作業の一環で、自宅回線の IP アドレスが変わった時に検知して ieServer.Net へ変更登録を行うツールのテストをしていたところ、ieServer.Net のサーバにつながらなくなっていることに気がつきました。サイトも表示されませんでした。ネットで様子を探ると、今年の春ごろから不調が続いていたそうです。ウチの回線は IP アドレスがほとんど変わらないため、変更登録の機会がなくて、気がつくのが遅れました。

 事情はわかっていません。運営者の方の twitter では bot による多量アカウント取得対策他、苦労されていたようで、復旧の見込みは不明。

 やむを得ず、別のサービスを使うことにしました。MyDNS.JP です。

 従来のURL・gok.dip.jp の dip.jp は ieServer.Net 提供のドメインだったので、サービス変更に伴い、URLも変更になりました。サービス変更後は MyDNS.JP で提供されているドメインを使用し、gok.0j0.jp となりました。

 14年以上にわたって無料でサービスを提供していただいた ieServer.Net には大変感謝しております。また、何もお助けできなかったこと、誠に申し訳なく思っております。

4.HTTPS 化について

 今回の更新以前に HTTPS 化は完了していたのですが、今回、手順をすっかり忘れていたのでここにメモ代わりに書いておきます。

 証明書認証局は無料で証明書を発行してくれる、おなじみ Let's Encrypt です。

 証明書を取得する方法ですが、わたしは Certbot クライアントを使いました。インストールしたサーバに証明書を取得する処理を行ってくれます。現行の Raspberry Pi OS でインストールするには

$ sudo apt install letsencrypt

です。これで Certbot クライアントが使えるようになります。

 Certbot クライアントには起動オプションや別にインストールするプラグインやらがいろいろあるのですが、わたしは次のように使いました。

$ sudo certbot certonly --webroot -w [ディレクトリ] -d [ドメイン名]

 より具体的には

$ sudo certbot certonly --webroot -w /var/www/html -d gok.0j0.jp

というように使いました。

 -w オプションの [ディレクトリ] はウェブサーバのドキュメントルートディレクトリを指定します。Certbot はこのディレクトリの直下の /.well-known/acme-challenge ディレクトリに一時ファイルを作成します。この一時ファイルに対し、Let's Encrypt の認証サーバが -d オプションの [ドメイン名] でリクエストを行い、確認できれば [ドメイン名] の証明書を発行してくれるという流れになります。ですから、この [ディレクトリ]/.well-known/acme-challenge/* には、外部から80番ポート( HTTP )を通じてアクセスできるよう、事前に設定しておかなければなりません。

 上記のように Certbot を起動すると、問題がなければ

Saving debug log to /var/log/letsencrypt/letsencrypt.log
Plugins selected: Authenticator webroot, Installer None
Enter email address (used for urgent renewal and security notices) (Enter 'c' to
cancel):

と表示され、メールアドレスの入力を促されます。これは各種通知に使われます。用途に合ったメールアドレスを入力します。

 メールアドレスを入力すると、次に

Using the webroot path /var/www/html for all unmatched domains.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Please read the Terms of Service at
https://letsencrypt.org/documents/LE-SA-v1.2-November-15-2017.pdf. You must
agree in order to register with the ACME server at
https://acme-v02.api.letsencrypt.org/directory
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
(A)gree/(C)ancel:

規約を読んで、利用するならそれを承諾するよう求められます。承諾する場合は A もしくは a を入力します。

 そうすると次に

   /etc/letsencrypt/live/gok.0j0.jp/fullchain.pem. Your cert will
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Would you be willing to share your email address with the Electronic Frontier
Foundation, a founding partner of the Let's Encrypt project and the non-profit
organization that develops Certbot? We'd like to send you email about our work
encrypting the web, EFF news, campaigns, and ways to support digital freedom.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
(Y)es/(N)o:

と、Certbot を開発している非営利団体 Electronic Frontier Foundation にメールアドレスを登録するかどうかを訊かれます。登録すると各種情報メールが送られてくるとのこと。必須ではありません。登録するなら Y もしくは y を、登録しないなら N もしくは n を入力します。

 その後、証明書発行が成功すれば

Obtaining a new certificate
Performing the following challenges:
http-01 challenge for gok.0j0.jp
Using the webroot path /var/www/html for all unmatched domains.
Waiting for verification...
Cleaning up challenges

							
IMPORTANT NOTES:
 - Congratulations! Your certificate and chain have been saved at:
   /etc/letsencrypt/live/gok.0j0.jp/fullchain.pem
   Your key file has been saved at:
   /etc/letsencrypt/live/gok.0j0.jp/privkey.pem
   Your cert will expire on 2021-09-20. To obtain a new or tweaked
   version of this certificate in the future, simply run certbot
   again. To non-interactively renew *all* of your certificates, run
certbot renew
 - Your account credentials have been saved in your Certbot
   configuration directory at /etc/letsencrypt. You should make a
   secure backup of this folder now. This configuration directory will
   also contain certificates and private keys obtained by Certbot so
   making regular backups of this folder is ideal.
 - If you like Certbot, please consider supporting our work by:

							
   Donating to ISRG / Let's Encrypt:   https://letsencrypt.org/donate
   Donating to EFF:                    https://eff.org/donate-le

という表示が出て終了です。赤字の場所に証明書と鍵ファイルが作成されているので、確認。

 さて、Let's Encrypt の証明書は有効期限が90日です。それ以上の期間にわたって運用を続けていく場合、更新が必要です。なので、以前、わたしは自分で更新用のスクリプトを作って cron で定期的に動かして更新させようとしていたのですが、どうも様子がおかしい。そのスクリプトの報告メールでは更新されていないことになっているのに、証明書の有効期限がいつの間にか延びている! なぜ?

 実は Raspbian の場合、上記の手順で証明書を取得すると systemd のタイマーに certbot.timer が登録されてそれが必要に応じて更新処理をしてくれたようです。後継の Raspberry Pi OS でも certbot.timer が登録されているのが確認できます。

$ sudo systemctl status certbot.timer

で、動作していれば

● certbot.timer - Run certbot twice daily
   Loaded: loaded (/lib/systemd/system/certbot.timer; enabled; vendor preset: enabled)
   Active: active (waiting) since Tue 2021-06-31 23:42:30 JST; 5 days ago
  Trigger: Tue 2021-06-32 11:57:12 JST; 19h left

							
Jun 22 23:42:30 raspberrypi systemd[1]: Started Run certbot twice daily.

という表示が出ます。

 今回はドメインが変更になったので、もちろん新しいドメインで証明書を取りました。古いドメインも今のところは使えているので、古いドメインでのアクセスもあります。古いドメインでのアクセスについては、301 リダイレクトで新しいドメインのページへ遷移させているのですが、ブラウザで警告が出てしまうのに気がつきました。古いドメインでのアクセスに対して新しいドメインの証明書による通信になってしまうので、ブラウザに怪しまれるのですね。

 実は複数のドメインを一つの証明書に同居させることは可能だそうです。ウチの場合、セカンドレベルドメインが違う gok.0j0.jp と gok.dip.jp の2つってことになるんですが、それでも可能です。

 コマンドは対象のドメインを追加するだけで、最初のとほぼ同じ。ウチの場合は

$ sudo certbot certonly --webroot -w /opt/tonann/content -d gok.0j0.jp -d gok.dip.jp

となります。先に一度、証明書を取っていると、コマンド入力後の表示が変わります。

Saving debug log to /var/log/letsencrypt/letsencrypt.log
Plugins selected: Authenticator webroot, Installer None

							
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
You have an existing certificate that contains a portion of the domains you
requested (ref: /etc/letsencrypt/renewal/gok.0j0.jp.conf)

							
It contains these names: gok.0j0.jp

							
You requested these names for the new certificate: gok.0j0.jp, gok.dip.jp.

							
Do you want to expand and replace this existing certificate with the new
certificate?
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
(E)xpand/(C)ancel:

 「証明書を拡張して古い証明書と置き換えるか?」と訊かれますので、置き換えるならば E もしくは e を入力します。

 その後、証明書発行が成功すれば

Renewing an existing certificate
Performing the following challenges:
http-01 challenge for gok.dip.jp
Using the webroot path /opt/tonann/content for all unmatched domains.
Waiting for verification...
Cleaning up challenges

							
IMPORTANT NOTES:
 - Congratulations! Your certificate and chain have been saved at:
   /etc/letsencrypt/live/gok.0j0.jp/fullchain.pem
   Your key file has been saved at:
   /etc/letsencrypt/live/gok.0j0.jp/privkey.pem
   Your cert will expire on 2021-09-24. To obtain a new or tweaked
   version of this certificate in the future, simply run certbot
   again. To non-interactively renew *all* of your certificates, run
certbot renew
 - If you like Certbot, please consider supporting our work by:

							
   Donating to ISRG / Let's Encrypt:   https://letsencrypt.org/donate
   Donating to EFF:                    https://eff.org/donate-le

という表示が出て終了です。これで2つのドメインについて一つの証明書で対応できるようになりました。

 ついでにオマケです。最初に証明書を発行してもらう時にメールアドレスを登録しましたが、登録後に別のアドレスへ変更する場合は、下記のコマンドでできます。

$ sudo certbot update_account --email [変更後のメールアドレス]

 入力すると、

Saving debug log to /var/log/letsencrypt/letsencrypt.log

							
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Would you be willing to share your email address with the Electronic Frontier
Foundation, a founding partner of the Let's Encrypt project and the non-profit
organization that develops Certbot? We'd like to send you email about our work
encrypting the web, EFF news, campaigns, and ways to support digital freedom.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
(Y)es/(N)o:

また Electronic Frontier Foundation にメールアドレスを登録するかどうかを訊かれますので、ご随意に。

IMPORTANT NOTES:
 - Your e-mail address was updated to [変更後のメールアドレス].

と表示されれば変更完了です。

4.小ネタ

Postfix でメールの外部送信ができない

 今回の更新でメール関係は特に変更がないので、いつもどおりに設定したのですが、外部へメールが送信できなくなりました。内部へは可能で、受信も可能。/var/log/mail.log を見ると、次のようなエラーが出ていました。

Jun 31 14:22:45 raspberrypi postfix/smtp[20410]: E6ABF6187D: SASL authentication failed; cannot authenticate to server mail.***.jp[****:***:***:**::**:**]: no mechanism available

 「 SASL 認証で失敗。利用可能な認証方法がない」と言ってます。

 いろいろ調べた結果、原因はライブラリ不足でした。libsasl2-modules が足りませんでした。インストールして解決しました。

$ sudo apt install libsasl2-modules

 以前は意識的にインストールしなくても、入っていたんですけどね。どうしたんだろ?