Raspberry Pi OSをBookwormへ移行した際、以前の環境ではそのまま動いていた設定やプログラムについて、いくつか修正が必要になりました。

今回は、実際に行った設定やトラブルへの対応をまとめておきます。

環境はRaspberry Pi OS 32bit Bookwormです。

1、localeのエラーを修正する

最初にaptなどを実行したところ、以下のような警告が表示されました。

apt-listchanges: Can't set locale
perl: warning: Setting locale failed
LANG = "ja_JP.UTF-8"

日本語localeが正しく生成されていないことが原因です。まずlocale関連のパッケージを確認し、設定します。

sudo apt update
sudo apt install locales
sudo dpkg-reconfigure locales

ja_JP.UTF-8 UTF-8を有効にし、既定のlocaleもja_JP.UTF-8に設定します。

sudo sed -i 's/^# *ja_JP.UTF-8 UTF-8/ja_JP.UTF-8 UTF-8/' /etc/locale.gen
sudo locale-gen
sudo update-locale LANG=ja_JP.UTF-8

設定後は以下で確認できます。

locale
locale -a | grep ja_JP
2、libpq-fe.hが見つからない

プログラムのビルド時にlibpq-fe.hが見つからない場合は、libpq-devをインストールします。

sudo apt install libpq-dev

通常は/usr/include/postgresql/libpq-fe.hにインストールされます。

dpkg -L libpq-dev | grep libpq-fe.h

古い環境から引き継いだlibssl1.0-devが入っていると、Bookwormのlibssl-devと競合する場合があります。

sudo apt purge libssl1.0-dev
sudo apt --fix-broken install
sudo apt update
sudo apt install libssl-dev libpq-dev
3、PHP 8.2をソースからビルドする

今回使用していたPHPのconfigureは以下のようなものでした。

./configure \\
  --enable-mbstring \\
  --with-openssl \\
  --with-iconv=/usr/local \\
  --with-apxs2=/usr/bin/apxs2 \\
  --enable-zts

PHP 8.2では古いlibssl1.0-devを使用する必要はなく、Bookworm標準のlibssl-devとOpenSSL 3を利用できます。

openssl version
pkg-config --modversion openssl
pkg-config --cflags --libs openssl

以前のビルド環境で設定した環境変数が残っている場合は、必要に応じて以下を解除します。

unset PKG_CONFIG_PATH
unset CPPFLAGS
unset CFLAGS
unset LDFLAGS
4、Mail/mimeDecode.phpを使うだけならPHPのビルドは不要

目的がPEARのMail/mimeDecode.phpを使用することだけであれば、PHPそのものをソースからビルドする必要はありませんでした。

sudo apt update
sudo apt install php php-cli php-mbstring php-pear
sudo pear install Mail_mimeDecode

インストール先は以下で確認できます。

find /usr/share/php -name mimeDecode.php

通常は/usr/share/php/Mail/mimeDecode.phpに入ります。

php -r "require_once 'Mail/mimeDecode.php'; echo 'OK\\n';"

今回の用途だけを考えると、PHPをソースからビルドするより、こちらのほうがかなり簡単でした。

5、Bookwormで固定IPを設定する

Raspberry Pi OS BookwormではNetworkManagerが使用されています。まず接続名を確認します。

nmcli connection show

たとえば接続名が有線接続 1だった場合、固定IPは以下のように設定できます。

sudo nmcli connection modify "有線接続 1" \\
  ipv4.method manual \\
  ipv4.addresses 192.168.1.100/24 \\
  ipv4.gateway 192.168.1.1 \\
  ipv4.dns "192.168.1.1 8.8.8.8"
sudo nmcli connection down "有線接続 1"
sudo nmcli connection up "有線接続 1"
ip addr show eth0
ip route

SSHで作業している場合、接続をdownした時点でSSHも切断されるため、設定した新しいIPアドレスへ再接続します。

6、タイムゾーンとNTPを設定する
sudo timedatectl set-timezone Asia/Tokyo
timedatectl
date

時刻同期にはsystemd-timesyncdを使用できます。

sudo timedatectl set-ntp true
sudo systemctl enable --now systemd-timesyncd
timedatectl timesync-status
7、cronから実行するとシェルスクリプトが動かない

通常のシェルからは動作するのに、cronから実行すると動かないという問題もありました。

#!/bin/sh
source /home/pi/venv/bin/activate

sourceはbashの組み込みコマンドなので、#!/bin/shで実行した場合には使用できないことがあります。

今回はvenvをactivateするのではなく、venv内のPythonを絶対パスで直接実行するように変更しました。

#!/bin/sh

cd /home/pi || exit 1
/usr/bin/getmail
/usr/bin/php /home/pi/example/maildecode.php \\
| /home/pi/venv/bin/python /home/pi/example/sendmessage.py
  • python、php、getmailなどは絶対パスで指定する
  • ログインシェルの環境変数がそのまま使えるとは考えない
  • HOMEやPATHに依存しすぎない
  • 外部サービス用の環境変数もcron側で利用できるようにする
* * * * * /home/pi/example.sh >> /home/pi/cron-example.log 2>&1

必要に応じてset -xを指定するのもデバッグに役立ちます。

8、LINE Bot SDK 3.xの警告を修正する

以前使用していたLINE Bot用のPythonプログラムでは旧APIを使用していました。

from linebot import LineBotApi
from linebot.models import TextSendMessage

line-bot-sdk 3.xではこれらが非推奨になっているため、新しいAPIへ変更しました。

from linebot.v3.messaging import (
    ApiClient,
    Configuration,
    MessagingApi,
    PushMessageRequest,
    TextMessage,
)

Channel Access Tokenや送信先IDなどは、ソースコードへ直接記述せず環境変数などで管理します。

export LINE_CHANNEL_ACCESS_TOKEN='...'
export LINE_USER_ID='...'

cronから実行する場合は、これらの環境変数についても注意が必要です。

9、SSH公開鍵認証を確認する

Bookwormへの移行後、SSHの公開鍵認証についても確認しました。

/home/pi                       700
/home/pi/.ssh                  700
/home/pi/.ssh/authorized_keys  600
sudo chown -R pi:pi /home/pi/.ssh
chmod 700 /home/pi/.ssh
chmod 600 /home/pi/.ssh/authorized_keys
sudo sshd -T | grep -E 'pubkeyauthentication|authorizedkeysfile'

鍵が本当に同じものか確認したい場合はfingerprintを比較します。

ssh-keygen -lf ~/.ssh/authorized_keys
ssh-keygen -lf ~/.ssh/id_rsa.pub

公開鍵ファイルが残っていない場合でも、秘密鍵から公開鍵を生成して確認できます。

ssh-keygen -y -f ~/.ssh/id_rsa > /tmp/id_rsa.pub
ssh-keygen -lf /tmp/id_rsa.pub
10、古いTera Termから公開鍵認証できない

古いTera Termから接続した場合に公開鍵認証が通らない問題がありました。

古いクライアントでは、RSA鍵の署名にssh-rsa(SHA-1)が使用される場合があります。一方、Bookworm側のOpenSSHではssh-rsaが標準で無効になっている場合があります。

互換性を確認するため、一時的にsshd側へ以下を設定する方法があります。

PubkeyAcceptedAlgorithms +ssh-rsa
sudo sshd -t
sudo systemctl restart ssh
sudo sshd -T | grep pubkeyaccepted

ただし、ssh-rsaを再び有効にする方法は古い環境との互換性を維持するための対応です。恒久的にはSSHクライアントを新しいバージョンへ更新し、ED25519などの新しい鍵へ移行するほうがよいでしょう。

ssh-keygen -t ed25519
11、まとめ

今回Raspberry Pi OSをBookwormへ移行してみると、OSそのものよりも、以前から使用していた周辺環境との違いでいくつか対応が必要になりました。

特に影響があったのは、OpenSSLの世代変更、NetworkManagerによるネットワーク設定、cronの実行環境、LINE Bot SDKのAPI変更、OpenSSHと古いSSHクライアントとの互換性あたりです。

一つずつ確認していけば特別難しい問題ではありませんが、古いRaspberry Pi環境を長く運用している場合には、複数の問題が同時に出てくることがあります。

今回の作業では、古い設定をそのまま再現するよりも、Bookwormの標準環境に合わせて不要になった設定を整理するほうが、結果として構成も分かりやすくなりました。