はじめに
SD カード上のブートローダーによる USB ストレージ起動を行なう環境を新規構築します。
本記事では、以下の略称を使用します。
-
Raspberry PiのことをPiと表記します。 -
USB ストレージのことをHDDと表記します。SSD を利用しても問題ないと思います。 -
sudoを介するコマンド実行部分を#プロンプトで表記します。
ちなみにSDカードを必要としない HDD 単体起動も Pi のモデルによっては可能ではあります。
インストール
イメージをダウンロードする
NOOBSよりはRaspbianそのもののほうが良いです。NOOBSは色々パーティションが作成されるので、ちょっと面倒そうでした。
ここでは公式からRaspbian Buster Liteをダウンロードしました。
Raspbian Buster Lite
Minimal image based on Debian Buster
Version:September 2019
Release date:2019-09-26
Kernel version:4.19
Size:426 MB
公式はかなり遅いので、ミラーサイトからダウンロートしたほうがよいかもしれません。
ブートローダー SD カードの準備
ダウンロードした img ファイルを SD カードに書き込み、bootパーティション直下にsshという空のファイルを作成します。
HDD の準備
ダウンロードした img ファイルを HDD に書き込み、bootパーティション直下にsshという空のファイルを作成します。
Pi の起動
SD カードのみ差し込んだ状態で Pi を起動します。しばらく待って ssh 接続を試みます。Pi が起動したかどうかは、なんとなく緑色の LED の点滅具合で判断します。何度か不定期に点滅し、その後に点滅しなくなったら起動できたと考えてよさそうです。そもそも緑色の LED が点灯しないならば起動してないと思います。
> ssh pi@192.168.1.100
pi@192.168.1.100's password:
初期ユーザーpiのパスワードはraspberryです。ログインが確認できたら HDD を USB 接続します。
パーディションサイズの拡大
現状、/dev/sda2のパーティションサイズが、HDD に書き込んだイメージサイズの大きさになっています。これを HDD の最大サイズに拡張します。
# fdisk /dev/sda
Device Boot Start End Sectors Size Id Type
/dev/sda1 8192 532480 524289 256M c W95 FAT32 (LBA)
/dev/sda2 540672 4292607 3751936 1.8G 83 Linux
まず、/dev/sda2パーテションを削除し、最大サイズで作成しなおします。この時、Startセクタは同じ値を設定します。Endセクタを HDD の最終セクタに指定します。
仕組みとしては、パーティションを削除しただけでは HDD の内容までは失われないので、すかさず同じ開始地点から、サイズを拡大した終了地点を指定し、最後にディスクに書き込むといった操作になります。
Command (m for help): d
Partition number (1,2, default 2): 2
Partition 2 has been deleted.
Command (m for help): n
Partition type
p primary (1 primary, 0 extended, 3 free)
e extended (container for logical partitions)
Select (default p):
Using default response p.
Partition number (2-4, default 2):
First sector (2048-3907029167, default 2048): 540672
Last sector, +/-sectors or +/-size{K,M,G,T,P} (540672-3907029167, default 3907029167):
Created a new partition 2 of type 'Linux' and of size 1.8 TiB.
Partition #2 contains a ext4 signature.
Do you want to remove the signature? [Y]es/[N]o: N
Command (m for help): w
The partition table has been altered.
Calling ioctl() to re-read partition table.
Syncing disks.
# resize2fs /dev/sda2
resize2fs 1.44.5 (15-Dec-2018)
Please run 'e2fsck -f /dev/sda2' first.
# e2fsck -f /dev/sda2
e2fsck 1.44.5 (15-Dec-2018)
Pass 1: Checking inodes, blocks, and sizes
Pass 2: Checking directory structure
Pass 3: Checking directory connectivity
Pass 4: Checking reference counts
Pass 5: Checking group summary information
rootfs: 42263/117360 files (0.2% non-contiguous), 313274/468992 blocks
つづいて、ファイルシステムサイズをパーティションサイズに合わせて拡張します。マウント中のファイルシステムに対しての操作にはなるので、問題がありそう? なさそう? という感じのメッセージが表示されますが、正常に拡張を行なうことができます。
# resize2fs /dev/sda2
resize2fs 1.44.5 (15-Dec-2018)
Filesystem at /dev/sda2 is mounted on /; on-line resizing required
old_desc_blocks = 1, new_desc_blocks = 117
The filesystem on /dev/sda2 is now 488311062 (4k) blocks long.
PARTUUID の確認
# blkid
/dev/mmcblk0p1: LABEL_FATBOOT="boot" LABEL="boot" UUID="F661-303B" TYPE="vfat" PARTUUID="d84d06b8-01"
/dev/mmcblk0p2: LABEL="rootfs" UUID="8d008fde-f12a-47f7-8519-197ea707d3d4" TYPE="ext4" PARTUUID="d84d06b8-02"
/dev/mmcblk0: PTUUID="d84d06b8" PTTYPE="dos"
/dev/sda1: LABEL_FATBOOT="boot" LABEL="boot" UUID="F661-303B" TYPE="vfat" PARTUUID="17869b7d-01"
/dev/sda2: LABEL="rootfs" UUID="8d008fde-f12a-47f7-8519-197ea707d3d4" TYPE="ext4" PARTUUID="17869b7d-02"
この結果はどこかにメモしておきます。重要なのは/dev/ではじまるデバイス名とPARTUUIDの値です。そして、どのパーティションなのかの判断材料としてLABEL_FATBOOTやLABELの値も意識しておきます。
デバイス名が/dev/mmcblk0pで始まるのが SD カードで、/dev/sdaで始まるのが HDD です。
/boot/cmdline.txtの編集
SD カード上のcmdline.txtを編集しますが、先にバックアップを作成しておきます。
# cp /boot/cmdline.txt /boot/cmdline.sd.txt
もし、この後の作業で SD カードからの起動ができなくなってしまった場合、SD カードを PC に接続し、バックアップしたファイルを/boot/cmdline.txtに書き戻したうえで Pi に SD カードを刺し直したうえで起動しなおします。
テキストエディタで/boot/cmdline.txtを開きます。
# vi /boot/cmdline.txt
dwc_otg.lpm_enable=0 console=serial0,115200 console=tty1 root=PARTUUID=5a25cb3e-02 rootfstype=ext4 elevator=deadline fsck.repair=yes rootwait
重要なのはroot=PARTUUID=の部分です。この値が、さきほどblkidした際にメモした SD カード上のLABEL="rootfsのPARTUUID値を示しています。これを/dev/sdaで始まるLABEL="rootfsのPARTUUID値に置き換えます。
これまでの手順通りならば、SD カードは/dev/mmcblk0p2、HDD は/dev/sda2であるはずです。もし違うなら読み替えてください。
dwc_otg.lpm_enable=0 console=serial0,115200 console=tty1 root=PARTUUID=17869b7d-02 rootfstype=ext4 elevator=deadline fsck.repair=yes rootwait
rebootし、再起動後に/root以下にどちらのファイルが存在するかで切り替えを判断したいと思います。
# reboot
しばらく待ち、ssh接続してみます。
> ssh pi@192.168.1.100
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@ WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED! @
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
IT IS POSSIBLE THAT SOMEONE IS DOING SOMETHING NASTY!
Someone could be eavesdropping on you right now (man-in-the-middle attack)!
It is also possible that a host key has just been changed.
(省略)
ECDSA host key for 192.168.1.100 has changed and you have requested strict checking.
Host key verification failed.
怒られました。これは、ホスト鍵が変化したために起こる問題です。この時点で HDD 起動に切り替わっていることが確認できたようなものです。この状態をリセットして、再度ssh接続を試みます。
> ssh-keygen -R 192.168.1.100
> ssh pi@192.168.1.100
pi@192.168.1.100's password:
はい、結果を見なくても確実ですね。パスワードraspberryを入力して HDD 側環境へログインします。
ここまでの作業で、SD カードからブートし、HDD 上のパーティションから OS がブートしたことが確認できました。
fstab の修正
/etc/fstab を確認します。注目すべきは/bootおよび/パーティションのPARTUUIDの値です。ここでは、bootパーティションは SD カード、/パーテションは HDD の UUID 値に修正します。
これが正しくおこなわれていないと、これ以降の作業でapt dist-upgradeなどを行なった後、rebootした際に不整合が発生します。
OS の更新
# apt dist-upgrade
パッケージ更新
まずは基本中の基本。パッケージを最新版に更新します。
# apt update
# apt upgrade
Wi-Fi と bluetooth を無効にする
今回用意したPiの運用目的はサーバーなので、無線通信を無効化します。
ぱっと見bluetoothはデーモンが起動しているように見えたので、systemctlから停止してみましたが、再起動すると復活していました。
調べてみると、/boot/config.txtというファイルがあるらしく、ここにサービスの停止を明示しないといけないようです。
systemctlの設定を無視する上位の設定ルールが存在するのはどうなのかな? と思いはするものの、まぁしょうがないです。
# Disable wifi and bluetooth.
dtoverlay=pi3-disable-wifi
dtoverlay=pi3-disable-bt
その他のオプションに関しては/boot/overlays/READMEに詳しく記載されています。
リブートします。
# reboot
pi ユーザーを置き換える
ユーザー名やパスワードが固定ということは、そこを突く攻撃に対応できないことになるので、ユーザー名とパスワードを変更したいと思います。
初期状態ではpiユーザーしか存在しないため、tmpユーザーを作成しsudoグループに所属させます。最後にパスワードを設定します。
# useradd -M tmp
# gpasswd -a tmp sudo
# passwd tmp
ログアウトし、tmpユーザーでログインします。
piユーザーを元とする、変更先のユーザーを作成します。ここではユーザー名をnewusernameとしていますが、お好きな名前に読み替えてください。
# usermod -l newusername pi
# usermod -d /home/newusername -m newusername
# groupmod -n newusername pi
newusername でログイン後、tmpユーザーを削除し自身のパスワードを変更します。
# userdel tmp
# passwd
ssh 接続用キーペアの作成と登録
非公開鍵と公開鍵のペアを作成し、サーバー側に公開鍵を登録しておきます。
キーペアの作成は通常クライアント側で行ないます。OpenSSH がインストールされた Windows 環境などでも作成可能です。
以下、OpenSSH がインストールされている場合の手順です。
C:\Users\localuser> ssh-keygen
Generating public/private rsa key pair.
Enter file in which to save the key (C:\Users\localuser/.ssh/id_rsa): ←基本的にはそのまま改行
Enter passphrase (empty for no passphrase): ←パスフレーズの入力
Enter same passphrase again: ←パスフレーズの再入力
ここまでの作業で、ホームフォルダの.sshフォルダ内にid_rsa.pubとid_rsaというファイルが作成されているはずです。
作成した公開鍵をサーバに登録します。登録するのはid_rsa.pubの内容です。
$ mkdir .ssh ←もしなければ作成
$ vi .ssh/authorized_keys
(ssh-rsa で始まる長い文字列を張り付けて保存)
「ローカル側にあるid_rsa.pubの内容を、サーバの.ssh/authorized_keysに追加登録する」という作業なので、追加登録が終わった後は、ローカル側にあるid_rsa.pubを消しても問題はありません。
プライベートキーであるid_rsaファイルは、わかりやすい名前に変更しておきます。
この時点で公開鍵をつかったログインができるか確認しておきましょう。さもないと、これ以降の作業でパスワードでのログインを禁止するため、リモートからログインできない環境が出来上がってしまう可能性があります。
問題なさそうならパーミッションも変更しておきます。
$ chmod 600 ~/.ssh/authorized_keys
$ chmod 700 ~/.ssh
公開鍵認証でのログインに限定し root でのログインを禁止する
パスワード認証を禁止し、公開鍵を利用したログインに限定します。
[root@centos ~]# vi /etc/ssh/sshd_config
# PermitRootLogin yes
↓
PermitRootLogin no ←コメントをはずし no に
# PasswordAuthentication yes
↓
PasswordAuthentication no ←コメントをはずし no に
[root@centos ~]# systemctl restart sshd.service ← sshd 再起動
上記設定後、これまで作成したアカウントでのパスワードログインができなくなっていることを確認しておいてください。同時に root での公開鍵ログインができないこと、作業ユーザーで公開鍵でのログインができることも確認しておきましょう。
タイムゾーンの変更
raspi-configコマンドにて変更します。テキストによる簡易 GUI 表示となるので、ターミナルソフトによっては画面がチラつくことがあります。Windows の場合、コマンドプロンプトでは問題ありませんでした。
-
4 Localisation Optionsを選択する -
I2 Change Timezoneを選択する -
Asiaを選択する -
Tokyoを選択する -
Finishを選択する