1. HOME
  2. テックブログ
  3. ラズベリーパイを(たぶん)快適にする(はずの)、かじってる人でも知らない世界

ラズベリーパイを(たぶん)快適にする(はずの)、かじってる人でも知らない世界

※今回の内容はかなりハードです。間違いなく万人受けはしません。
「こんなコトをしている場合がある」ということについての記録なのかもしれません。

社内でラズベリーパイというデバイスを使って遊んでインターン向けで使っていたりしています。

その中で使われる公式のOSがRaspbianと呼ばれ、 Debian と呼ばれるLinuxディストリビューションをベースで作られています。(ディストリビューションとはこの場合配布形態と訳され、多少語弊はあるかもしれませんが「LinuxカーネルをOSとして使える状態にするもの」と考えて良いでしょう)
もちろん、Debian以外を使いたいという方々は世界にいらっしゃいまして、Fedoraという別のディストリビューションベースのpidoraなどと結構色々とあるので、チャレンジャーな方は試してみると良いのではないでしょうか。

実際このDebianなんですが、私自身は20年以上サーバ/デスクトップ環境の両方で使い続けていて、インターンの準備で若手メンバーがキーボードレイアウトを日本語配列に変更するとか、ターミナルの画面で日本語表示をデフォルトにするなどはちょっとしたお作法があるんですが、そこで悩んでいるところを見てニヤニヤフォローすることがあります。

通常のDebianであれば今の時代は使用にはほぼ問題ないのでしょうけれど、ラズベリーパイでは英語が基本で多言語対応はデフォルトではそこまでできていませんし、またDebian自体もそのような面も無いわけではなく、慣れていないとなかなか厳しいところがあります。

例えば、圧縮されたzipファイルを展開する時に使うunzipコマンドなどは、日本語ファイル名に対応できておらず、展開するとファイル名が文字化けしたまま展開されるなど、非常に面倒なことになります(※)。
そのためDebianの派生ディストリビューションのUbuntuなどでは日本語コミュニティチームが対応するパッチをあてて使えるようにする…ということを行っています。

※こんな時はThe Unarchiverのunarコマンドのパッケージを入れてしまえば良いという話はあります。

そこで「ラズベリーパイの環境に対してでも同じことをして使いづらいRaspbianを少しでも都合が良いように作り変えよう!」というのが今回の話です。

ゴールへの道筋としては、

クロスコンパイルを行って
(ソースコードから開発に使う環境/OSとは異なる環境向けに動作するソフトウェアを作る行為)
⬇︎
ラズベリーパイ用のパッケージを作って
⬇︎
社内にある複数のラズベリーパイにインストールする

ということになります。

実際に何をする必要があるかというのは下記の通り。

1. Debianを普通にインストールしたPCを準備する
2. クロスコンパイル環境を作る
3. unzip用のパッチを入手する
4. パッチをあててDebian用のパッケージを作る
5. パッケージをインストールして使えるようにする

なお、Debianのインストール自体は「USBメモリ用とかDVD用とかのイメージをダウンロードして、インストールメディアを作成して、インストールする際に自動でインストールする」というレベルでも問題ないはず…ということでインストールの手順と、下記手順内ではちょっとしたwarning等は一般的な使い方をしていれば表示されない部分について、省いています。

では、具体的な手順とその実行を行ってみます。

1. クロスコンパイル環境を作るために母艦となるDebian上で、必要なパッケージをインストール

ひとまずschroot debootstrapqemu-user-staticをインストールします。

  • schrootは使っている環境の中に仮想の別環境に移行して作業するため
  • debootstrapはDebianの環境を仮想環境等に作るため
  • qemu-user-staticはQEMUと呼ばれる仮想環境を作るため

ということになります。

これらを使うことで、通常の開発環境/テスト環境をホストマシンに影響を与えることなくパッケージを作ることができるので非常に便利です。

これらを使うことで、通常の開発環境/テスト環境をホストマシンに影響を与えることなくパッケージを作ることができるので非常に便利です。

~% sudo apt install schroot debootstrap qemu-user-static
パッケージリストを読み込んでいます... 完了
依存関係ツリーを作成しています
状態情報を読み取っています... 完了
以下の追加パッケージがインストールされます:
arch-test schroot-common
提案パッケージ:
squid-deb-proxy-client aufs-tools | unionfs-fuse
以下のパッケージが新たにインストールされます:
arch-test debootstrap qemu-user-static schroot schroot-common
アップグレード: 0 個、新規インストール: 5 個、削除: 0 個、保留: 2 個。
23.1 MB 中 22.8 MB のアーカイブを取得する必要があります。
この操作後に追加で 221 MB のディスク容量が消費されます。
続行しますか? [Y/n] <strong>←ここでyを押すかエンターを押す</strong>
取得:1 http://ftp.jp.debian.org/debian sid/main amd64 arch-test all 0.16-2 [12.8 kB]
取得:2 http://ftp.jp.debian.org/debian sid/main amd64 qemu-user-static amd64 1:4.2-3 [21.9 MB]
(以下インストール状況の表示なので省略)

2.クロスコンパイル環境を作る

Debianの現在のリリース版コードネーム(ちなみにトイ・ストーリーのキャラクターです)を指定して、開発環境をインストールするということをやっています。

一通りのパッケージ群をダウンロードして展開しているので結構時間がかかるのと、ネットの接続環境が必要になります。
たぶん進みだしてしまえば、あとは待つばかりです。

~% sudo qemu-debootstrap --arch=armhf buster /chroot/armhf http://ftp.debian.org/debian/
I: Running command: debootstrap --arch armhf --foreign buster /chroots/armhf http://ftp.debian.org/debian/
I: Retrieving InRelease
I: Checking Release signature
I: Valid Release signature (key id 6D33866EDD8FFA41C0143AEDDCC9EFBF77E11517)
I: Retrieving Packages
I: Validating Packages
I: Resolving dependencies of required packages...
I: Resolving dependencies of base packages...
I: Checking component main on http://ftp.debian.org/debian...
I: Retrieving libacl1 2.2.53-4
I: Validating libacl1 2.2.53-4
I: Retrieving adduser 3.118
(パッケージをダウンロードされインストールされるところなので省略)
I: Configuring libc-bin...
I: Configuring systemd...
I: Base system installed successfully.

3.chrootというコマンドで仮想環境に移行し、パッケージデータベースの情報にソースコードを取得するための情報を追加する

インストールされた環境に移行して動作するか試します…が、たいてい前の作業にエラーが無い限りちゃんと動きます。
ただデフォルトの状態はリポジトリからソースコードをを取得できないので、取得先の情報を追加をしておきます。

なお、デバイスやプロセスの情報などをホストPCと共有するなどをしておくと楽ではあるんですが、今回はパッケージ作成がメインなので省略しています。
(興味のある方は「mount –bind chroot」などと調べてみましょう。)

4.パッケージ情報を更新し、開発に必要なパッケージをインストールする

これ以降、自分のPCの中だとか、色々手間があるので全てroot権限で動かしてしまっています。同じように試す場合、セキュリティ面を気にしつつ適切な状況で行ってください。

devscriptsはDebianのパッケージ(.debファイル)を作るための各種パッケージを一度に入れてくれるメタパッケージと呼ばれるものです。
メタパッケージは依存する別のパッケージを指定しておき、1つ入れるだけで動作させる時に依存する他のパッケージも引き連れてインストールしてくれるものです。

なお個人的にエディタとしてvimを入れていますが、今回のこの記事ではパッケージを作り直すだけであればvimを必要としない格好で各コマンドを連ねていますが、コード等の修正時に苦行を厭わないのであれば入れる必要はないと思います。

root@armhf:/# apt update
Hit:1 http://ftp.debian.org/debian buster InRelease
Get:2 http://ftp.debian.org/debian buster/main Sources [7832 kB]
Get:3 http://ftp.debian.org/debian buster/main Translation-en [5969 kB]
Fetched 13.8 MB in 10s (1422 kB/s)
Reading package lists... Done
Building dependency tree... Done
All packages are up to date.
root@armhf:/# apt install vim devscripts
パッケージリストを読み込んでいます... 完了
依存関係ツリーを作成しています
状態情報を読み取っています... 完了
以下の追加パッケージがインストールされます:
at autoconf automake autopoint autotools-dev binutils binutils-arm-linux-gnueabihf binutils-common build-essential bzip2
ca-certificates cpp cpp-8 curl dctrl-tools debhelper debian-keyring dh-autoreconf dh-strip-nondeterminism diffstat dirmngr
distro-info-data dpkg-dev dput dwz equivs exim4-base exim4-config exim4-daemon-light fakeroot file g++ g++-8 gcc gcc-8 gettext
(大量に出てくるので省略)
mime-support (3.62) のトリガを処理しています ...
libc-bin (2.28-10) のトリガを処理しています ...
systemd (241-7~deb10u2) のトリガを処理しています ...
man-db (2.8.5-2) のトリガを処理しています ...

5.unzipのDebianのリポジトリからソースコードを取得する

aptコマンドでソースを取得するオプションを指定すれば、勝手にアーカイブを展開までしてくれます。
もちろんリポジトリから直接関連するファイルをダウンロードしてコマンドで同じように展開する…というのも可能です。

ちなみにDebianのパッケージはバイナリファイルとコントロールそれぞれがtar+xzでまとめられたアーカイブを、さらにarコマンドでアーカイブしているので、システム的に壊れかけていてもなんとかなる可能性があります。

root@armhf:/# mkdir ~/src
root@armhf:/# cd
root@armhf:~/src# apt source unzip
パッケージリストを読み込んでいます... 完了
1,401 kB のソースアーカイブを取得する必要があります。
取得:1 http://ftp.debian.org/debian buster/main unzip 6.0-23+deb10u1 (dsc) [1,376 B]
取得:2 http://ftp.debian.org/debian buster/main unzip 6.0-23+deb10u1 (tar) [1,377 kB]
取得:3 http://ftp.debian.org/debian buster/main unzip 6.0-23+deb10u1 (diff) [23.0 kB]
1,401 kB を 2秒 で取得しました (671 kB/s)
dpkg-source: info: extracting unzip in unzip-6.0
dpkg-source: info: unpacking unzip_6.0.orig.tar.gz
dpkg-source: info: unpacking unzip_6.0-23+deb10u1.debian.tar.xz
dpkg-source: info: using patch list from debian/patches/series
dpkg-source: info: applying 01-manpages-in-section-1-not-in-section-1l.patch
dpkg-source: info: applying 02-this-is-debian-unzip.patch
dpkg-source: info: applying 03-include-unistd-for-kfreebsd.patch
dpkg-source: info: applying 04-handle-pkware-verification-bit.patch
dpkg-source: info: applying 05-fix-uid-gid-handling.patch
dpkg-source: info: applying 06-initialize-the-symlink-flag.patch
dpkg-source: info: applying 07-increase-size-of-cfactorstr.patch
dpkg-source: info: applying 08-allow-greater-hostver-values.patch
dpkg-source: info: applying 09-cve-2014-8139-crc-overflow.patch
dpkg-source: info: applying 10-cve-2014-8140-test-compr-eb.patch
dpkg-source: info: applying 11-cve-2014-8141-getzip64data.patch
dpkg-source: info: applying 12-cve-2014-9636-test-compr-eb.patch
dpkg-source: info: applying 13-remove-build-date.patch
dpkg-source: info: applying 14-cve-2015-7696.patch
dpkg-source: info: applying 15-cve-2015-7697.patch
dpkg-source: info: applying 16-fix-integer-underflow-csiz-decrypted.patch
dpkg-source: info: applying 17-restore-unix-timestamps-accurately.patch
dpkg-source: info: applying 18-cve-2014-9913-unzip-buffer-overflow.patch
dpkg-source: info: applying 19-cve-2016-9844-zipinfo-buffer-overflow.patch
dpkg-source: info: applying 20-cve-2018-1000035-unzip-buffer-overflow.patch
dpkg-source: info: applying 21-fix-warning-messages-on-big-files.patch
dpkg-source: info: applying 22-cve-2019-13232-fix-bug-in-undefer-input.patch
dpkg-source: info: applying 23-cve-2019-13232-zip-bomb-with-overlapped-entries.patch
dpkg-source: info: applying 24-cve-2019-13232-do-not-raise-alert-for-misplaced-central-directory.patch

6.パッチをダウンロードし、パッケージの情報に組み込む

パッチとは、ソースコードを一部改変する差分データのことで、若干の機能改修やバグ修正など、差分情報が書かれているファイルです。
これを取込み日本語を使えるようにします。

今回はcurlでダウンロードする際にSSL証明書のチェックを省いていますが、本来であれば環境を整えた上で接続先を検証しながら行ったほうが良いでしょう。
Debianのパッケージを作る際にパッチを置く場所に移動し、そこでパッチをダウンロード後、あてるパッチを指定するファイルにファイル名を書き込み、正しく書き込まれているか確認します。

root@armhf:/# cd unzip-6.0/debian/patches
root@armhf:~/src/unzip-6.0/debian/patches# curl -k "https://bugs.archlinux.org/task/15256?getfile=3685" -o 25-unzip60-alt-iconv-utf8.patch
root@armhf:~/src/unzip-6.0/debian/patches# echo 25-unzip60-alt-iconv-utf8.patch >> series
root@armhf:~/src/unzip-6.0/debian/patches# cat series
01-manpages-in-section-1-not-in-section-1l.patch
02-this-is-debian-unzip.patch
03-include-unistd-for-kfreebsd.patch
04-handle-pkware-verification-bit.patch
05-fix-uid-gid-handling.patch
06-initialize-the-symlink-flag.patch
07-increase-size-of-cfactorstr.patch
08-allow-greater-hostver-values.patch
09-cve-2014-8139-crc-overflow.patch
10-cve-2014-8140-test-compr-eb.patch
11-cve-2014-8141-getzip64data.patch
12-cve-2014-9636-test-compr-eb.patch
13-remove-build-date.patch
14-cve-2015-7696.patch
15-cve-2015-7697.patch
16-fix-integer-underflow-csiz-decrypted.patch
17-restore-unix-timestamps-accurately.patch
18-cve-2014-9913-unzip-buffer-overflow.patch
19-cve-2016-9844-zipinfo-buffer-overflow.patch
20-cve-2018-1000035-unzip-buffer-overflow.patch
21-fix-warning-messages-on-big-files.patch
22-cve-2019-13232-fix-bug-in-undefer-input.patch
23-cve-2019-13232-zip-bomb-with-overlapped-entries.patch
24-cve-2019-13232-do-not-raise-alert-for-misplaced-central-directory.patch
25-unzip60-alt-iconv-utf8.patch ←これ!!

7.unzipのパッケージ作成で必要なパッケージを追加する

パッケージを作る際に依存するライブラリがいくつかありますが、デフォルトで入っているとは限りません。

ただDebianではパッケージをビルドし直す時用にコマンド1つで、ビルド時に依存するパッケージもインストールできます。悩まなくてイイんです。
たぶん前述のdevscriptを入れた時にあらかたインストールされていたのでlibbz2-devパッケージだけのようでした。

root@armhf:~/src/unzip-6.0/debian/patches# cd ~/src/unzip-6.0
root@armhf:~/src/unzip-6.0# apt build-dep unzip
パッケージリストを読み込んでいます... 完了
パッケージリストを読み込んでいます... 完了
依存関係ツリーを作成しています
状態情報を読み取っています... 完了
以下のパッケージが新たにインストールされます:
libbz2-dev
アップグレード: 0 個、新規インストール: 1 個、削除: 0 個、保留: 0 個。
28.8 kB のアーカイブを取得する必要があります。
この操作後に追加で 72.7 kB のディスク容量が消費されます。
続行しますか? [Y/n]
取得:1 http://ftp.debian.org/debian buster/main armhf libbz2-dev armhf 1.0.6-9.2~deb10u1 [28.8 kB]
28.8 kB を 1秒 で取得しました (27.6 kB/s)
以前に未選択のパッケージ libbz2-dev:armhf を選択しています。
(データベースを読み込んでいます ... 現在 32151 個のファイルとディレクトリがインストールされています。)
.../libbz2-dev_1.0.6-9.2~deb10u1_armhf.deb を展開する準備をしています ...
libbz2-dev:armhf (1.0.6-9.2~deb10u1) を展開しています...
libbz2-dev:armhf (1.0.6-9.2~deb10u1) を設定しています ...

8.パッケージの情報を変更しビルドする

ビルド前に自作パッケージ用にリビルドした人の名前やメールアドレスやリリースバージョン、修正時のコメントを打ち込んでいます。
このパッケージが外部に出回ってしまった時に、パッケージメンテナーに連絡が取れるように…というお作法でもあります。

この情報はソースコードのディレクトリの中にあるdebianというディレクトリのchangelogの一番上に書かれます。もちろんこのファイルも手動で書き直すことでも問題ありません。
その後パッケージ作成のため、プログラムのコンパイルやパッケージに必要な情報をまとめたり、パッケージの作成状況に問題がないかなどのチェックをしてくれるメタコマンドに引き渡します。

最後のパッケージができる時に、公式のパッケージでは、本来自分が作ったと電子的な署名を残すのですが、今回はローカルでしか使わないので電子署名を残すことはせず一旦スルーします。

root@armhf:~/src/unzip-6.0# DEBFULLNAME='SAITO Naohiko' DEBEMAIL='example@example.com' dch --bpo "with utf-8 patch"
root@armhf:~/src/unzip-6.0# debuild -us -uc -rfakeroot
dpkg-buildpackage -rfakeroot -us -uc -ui
dpkg-buildpackage: info: source package unzip
dpkg-buildpackage: info: source version 6.0-23+deb10u1~bpo10+1
dpkg-buildpackage: info: source distribution buster-backports
dpkg-buildpackage: info: source changed by SAITO Naohiko <example@example.com>
dpkg-source --before-build .
dpkg-buildpackage: info: host architecture armhf
dpkg-source: info: using patch list from debian/patches/series
dpkg-source: info: applying 01-manpages-in-section-1-not-in-section-1l.patch
dpkg-source: info: applying 02-this-is-debian-unzip.patch
dpkg-source: info: applying 03-include-unistd-for-kfreebsd.patch
(略)
dpkg-buildpackage: info: binary and diff upload (original source NOT included)
Now running lintian unzip_6.0-23+deb10u1~bpo10+1_armhf.changes ...
warning: the authors of lintian do not recommend running it with root privileges!
W: unzip source: maintainer-script-lacks-debhelper-token debian/postinst
W: unzip source: maintainer-script-lacks-debhelper-token debian/postrm
W: unzip source: changelog-should-mention-nmu
W: unzip source: debian-rules-sets-dpkg-architecture-variable DEB_HOST_GNU_TYPE (line 5)
W: unzip source: ancient-standards-version 3.9.6 (released 2014-09-17) (current is 4.3.0)
W: unzip: manpage-has-errors-from-man usr/share/man/man1/zipinfo.1.gz 349: warning: macro 'mF' not defined
Cannot open /proc/1255495/fd, falling back to generic method - No such file or directory at /usr/share/perl5/IO/Async/OS/linux.pm line 38.
N: 0 tags overridden; 1 unused override
Finished running lintian.

9.パッケージをインストールする。

ソースコードの1つ上のディレクトリに、ビルドしたパッケージとその他のソースコードなどと一緒に置かれています。

今回はdpkgコマンドでインストールしてみましょう。バージョンが「ダウングレードする」と言われていますが、前述のdchコマンドの発行のところでバージョンを少し上で指定をすると、後日のパッケージアップデートで手間は減ります。

root@armhf:~/src/unzip-6.0# cd ../
root@armhf:~/src# dpkg -i unzip_6.0-23+deb10u1~bpo10+1_armhf.deb
dpkg: 警告: unzip を 6.0-23+deb10u1 から 6.0-23+deb10u1~bpo10+1 にダウングレードしています
(データベースを読み込んでいます ... 現在 33618 個のファイルとディレクトリがインストールされています。)
unzip_6.0-23+deb10u1~bpo10+1_armhf.deb を展開する準備をしています ...
unzip (6.0-23+deb10u1~bpo10+1) で (6.0-23+deb10u1 に) 上書き展開しています ...
unzip (6.0-23+deb10u1~bpo10+1) を設定しています ...
mime-support (3.62) のトリガを処理しています ...
man-db (2.8.5-2) のトリガを処理しています ...

10.試す

Windows上で日本語フォルダを作り、その中で日本語ファイル名を使ったファイルをフォルダごとzip化しておき、それをラズパイ側に送ります。

WindowsのデフォルトはShift-JIS(CP932)ということですので、-Oオプションで指定してあげます。MacなどUTF-8ベースのものであれば「-O cp932」を抜くだけでも大丈夫です。
(なお下記の手順は-tオプションを使用してテストモードで展開まではしていません。)

root@armhf:/tmp# unzip -t -O cp932 日本語ディレクトリ.zip
Archive: 日本語ディレクトリ.zip
testing: 日本語ディレクトリ/日本語テキストファイル.txt OK
No errors detected in compressed data of 日本語ディレクトリ.zip.

まとめ

これでラズパイを楽しく活用するためにDebianパッケージを作るという手順はおしまいです。
自分で作って動かすだけであれば、ラズパイのリポジトリに依存せずに色々できることが薄っすらとでも解っていただけたかと思います。

もちろん全てを一からパッケージを作るというのはかなり難しいので、最初のうちは今回の話のようにパッチをあてて作り直すといったことが良いでしょう。

今でこそ公式・非公式によらず使えるパッケージの種類・数が多くなってきてはいるのであまりやらなくなりましたが、ファブリカコミュニケーションズのインフラチームでは数年前からパッケージを作るなどを行い、自社サービス維持・運用の助けにしていました。
サービスを維持しやすくするために、インストールの時間を短くするとか簡単にバージョンを変更できるようにするといった、サービスをできるだけ止めないための工夫でもあります。

ラズパイで色々遊ぶ以外にも、サーバ管理などに興味のある方は、このような部分も勉強されると良いかとは思います。

こんなインフラチームはいつでも人を募集していますので、興味のある方はぜひ応募してみてください。

ファブリカコミュニケーションズで働いてみませんか?

あったらいいな、をカタチに。人々を幸せにする革新的なサービスを、私たちと一緒に創っていくメンバーを募集しています。

ファブリカコミュニケーションズの社員は「全員がクリエイター」。アイデアの発信に社歴や部署の垣根はありません。

“自分から発信できる人に、どんどんチャンスが与えられる“そんな環境で活躍してみませんか?ご興味のある方は、以下の採用ページをご覧ください。

◎ 新卒採用の方はこちら
◎ キャリア採用の方はこちら

この記事を書いた人

齋藤 直彦
プロダクト開発本部 IT管理統括部長兼CISO
齋藤 直彦

おすすめの記事