Raspberry PiをHDDにヘッドレスセットアップ

[aratana Advent Calendar 2019](https://qiita.com/advent-calendar/2019/aratana)の2日目です。
![aratana](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/150455/e79ba51f-0163-246b-ad7b-998f8f442d72.png)

ラズパイセットアップする際、得にRaspbian Liteの場合、キーボードとかHDMI繋げるの面倒だなーって感じるかと思います。
ラズパイを初回起動する前に、必要な設定を行いすぐsshでログインできるような状態にします。
※USBブートではなく、MicroSDカードとHDDを使って、ルートファイルシステム部分をHDDにします。

dd, fdiskコマンドを利用するので、**間違っても大事なデータが入ってるデバイスに対して実行しないようにお願いします！消えちゃうので。**

# 必要なもの
1. Raspberry Pi (3B+, 4で検証済み)
1. MicroSDカード (4GB以上？)
1. HDD (2.5インチおすすめ)

※Linuxでセットアップします。

# はじめに

Raspbian Liteのダウンロード
https://www.raspberrypi.org/downloads/raspbian/


```bash
$ wget https://downloads.raspberrypi.org/raspbian_lite_latest -O raspbian_lite.zip
$ unzip raspbian_lite.zip
```

`2019-09-26-raspbian-buster-lite.img`のような名前のイメージファイルが解凍されるかと思います。

下準備として、このイメージファイルのループバックデバイスを作成します。
※ [Linuxでループバック・デバイスを扱う](https://qiita.com/aki-takano/items/55e0061e6d5fca78631f)

```terminal
// ループバックデバイス作成
# losetup -fP 2019-09-26-raspbian-buster-lite.img

// 確認 (基本的には/dev/loop0に登録されてる)
# losetup -l

// fdiskで詳細確認
# fdisk -l

Disk /dev/loop0: 2.1 GiB, 2248146944 bytes, 4390912 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: dos
Disk identifier: 0x6c586e13

Device       Boot  Start     End Sectors  Size Id Type
/dev/loop0p1        8192  532479  524288  256M  c W95 FAT32 (LBA)
/dev/loop0p2      532480 4390911 3858432  1.9G 83 Linux

// 確認
# lsblk -o name,label,partuuid

NAME      LABEL    PARTUUID
loop0
├─loop0p1 boot     6c586e13-01
└─loop0p2 rootfs   6c586e13-02
```

# HDD設定 (rootfs)
まずは、HDDの設定を行っていきます。

## HDDの確認
たぶん親が使ってた、HDD2.5インチを利用します。

```terminal
# fdisk -l

Disk /dev/sdc: 74.54 GiB, 80026361856 bytes, 156301488 sectors
Disk model: 0BEVE-00A0HT0
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: gpt
Disk identifier: BAB3CBAC-CE2E-984E-86FE-3257F8C2B95B
```

## パーティションの準備
**下記方法は、HDDデータ抹消されるので注意！**

上記で確認した、デバイスファイルに対して、rootfsパーティションを準備します。
**デバイスファイル間違えないように、データ消えちゃうので。。。**

```terminal
# fdisk /dev/sdc

// ディスクパーティションをGPTに設定
Command (m for help): g
Created a new GPT disklabel (GUID: 1EBE3472-7A65-5249-B5D4-A85C748BC20C).

// パーティション作成
Command (m for help): n
Partition number (1-128, default 1):
First sector (2048-156301454, default 2048):
Last sector, +/-sectors or +/-size{K,M,G,T,P} (2048-156301454, default 156301454):

Created a new partition 1 of type 'Linux filesystem' and of size 74.5 GiB.

// 確認 (1パーティションのみできてる)
Command (m for help): p
Disk /dev/sdc: 74.54 GiB, 80026361856 bytes, 156301488 sectors
Disk model: 0BEVE-00A0HT0
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: gpt
Disk identifier: 1EBE3472-7A65-5249-B5D4-A85C748BC20C

Device     Start       End   Sectors  Size Type
/dev/sdc1   2048 156301454 156299407 74.5G Linux filesystem

// 反映
Command (m for help): w
The partition table has been altered.
Calling ioctl() to re-read partition table.
Syncing disks.

// 確認
# lsblk -o name,label,partuuid
NAME      LABEL    PARTUUID
sdc
└─sdc1             3ea22dca-b930-624a-b409-0c4dfe85abf5
```

## rootfsを用意

ラズパイイメージ上のrootfsをコピーします。(ラベルが、rootfsになってるかと思います)

```terminal
# dd bs=4M if=/dev/loop0p2 of=/dev/sdc1

// イメージファイルの容量と設定したパーティションサイズが異なるので、チェック掛ける
# e2fsck -f /dev/sdc1

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: 44367/120720 files (0.3% non-contiguous), 292014/482304 blocks


//パーティションサイズを合わせる
# resize2fs /dev/sdc1

// 確認 (LABELがrootfsになってる)
# lsblk -o name,label,partuuid
NAME      LABEL    PARTUUID
sdc
└─sdc1    rootfs   3ea22dca-b930-624a-b409-0c4dfe85abf5
```

**↑PARTUUIDは、後ほど使うのでコピ！**


# rootfsの設定
rootfsの中身をいじります。

下記設定を事前に行っていきます。

1. fstabの修正 (参考: [fstabについて](https://qiita.com/kihoair/items/03635447591358210772))
1. 固定IPに設定 (動的でも良いが、探すのが面倒なため)
1. パーティションサイズのリサイズ起動しないようにする
1. 必要であれば、WiFi接続設定


とりあえずマウントしときます。

```terminal
// さっき作ったHDDをマウント
# mkdir root
# mount /dev/sdc1 root
```


## fstabの修正

```terminal
# cat root/etc/fstab
```

下記のように書かれている行がある。

```text
PARTUUID=6c586e13-02 / ext4 defaults,noatime  0 1
```

LABEL=rootfsに書き換えた (PARTUUIDの書き換えでもOK)

```text
LABEL=rootfs / ext4 defaults,noatime  0 1
```

## パーテイションサイズのリサイズ起動しないようにする
初回起動時に自動でパーティションリサイズが、かかってしまうので、起動しないように設定。

```terminal
# rm root/etc/rc3.d/S01resize2fs_once root/etc/init.d/resize2fs_once
```

## 固定IPに変更

下記の必要な値を書き換えて、root/etc/dhcpcd.confに追記します。

```
interface eth0
static ip_address=固定したいIP
static routers=ルータIP
static domain_name_servers=DNSのIP

interface wlan0
static ip_address=固定したいIP
static routers=ルータIP
static domain_name_servers=DNSのIP
```

## WiFi設定 (必要に応じて)
WiFi接続する場合は、下記実行。

```terminal
# bash -c "wpa_passphrase 接続するSSID パスワード >> root/etc/wpa_supplicant/wpa_supplicant.conf"

// 設定確認
# cat root/etc/wpa_supplicant/wpa_supplicant.conf 
```


# MicroSDカード設定 (boot領域設定)

```terminal
// 対象のMicroSDカードの確認
# fdisk -l

Disk /dev/sdb: 29.86 GiB, 32044482560 bytes, 62586880 sectors
Disk model: MassStorageClass
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: dos
Disk identifier: 0x6c586e13

// ラズパイファイルシステムをまるっとコピー
# dd bs=4M if=/dev/loop0 of=/dev/sdb conv=fsync

# lsblk -o name,label,partuuid

NAME      LABEL    PARTUUID
sdb
├─sdb1    boot     6c586e13-01
└─sdb2    rootfs   6c586e13-02

// SDカードのrootfsは, HDDで設定済みなので削除
fdisk /dev/sdb

// パーティション削除
Command (m for help): d
Partition number (1,2, default 2):

Partition 2 has been deleted.

// 確認 (パーティション1つになってる)
Command (m for help): p
Disk /dev/sdb: 29.86 GiB, 32044482560 bytes, 62586880 sectors
Disk model: MassStorageClass
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: dos
Disk identifier: 0x6c586e13

Device     Boot Start    End Sectors  Size Id Type
/dev/sdb1        8192 532479  524288  256M  c W95 FAT32 (LBA)

// 反映
Command (m for help): w
The partition table has been altered.
Calling ioctl() to re-read partition table.
Syncing disks.
```

## bootのファイル修正

下記設定を行います。

1. SSHデーモンの自動起動設定
1. cmdline.txtの変更

```terminal
# mkdir boot
# mount /dev/sdb1 boot

// ファイル作っとくだけでsshd自動起動してくれる
# touch boot/ssh

# cat boot/cmdline.txt

console=serial0,115200 console=tty1 root=PARTUUID=6c586e13-02 rootfstype=ext4 elevator=deadline fsck.repair=yes rootwait quiet init=/usr/lib/raspi-config/init_resize.sh

// リサイズしてるので不要
// quiet init=/usr/lib/raspi-config/init_resize.sh

// 設定したHDDのLABEL: rootfsのPARTUUIDを設定 (LABELだとうまくいかなかったので。。。)
// root=PARTUUID=6c586e13-02 -> root=PARTUUID=3ea22dca-b930-624a-b409-0c4dfe85abf5


// 結果こうなる
console=serial0,115200 console=tty1 root=PARTUUID=3ea22dca-b930-624a-b409-0c4dfe85abf5 rootfstype=ext4 elevator=deadline fsck.repair=yes rootwait
```

MicroSDカードとHDDをラズパイ接続して、電源いれれば起動されるかと思います。
最低限の設定は行っているので、あとは、指定したIPに対してssh接続してゴニョゴニョ設定してきましょう！



# おまけ
今回は、HDD全容量をrootfsにしましたが、
実際は、パーティション切ったりする方多いかと思います。

とりあえず、

```
/
/home
/var
```

上記パーティション切る方法も、載せておきます。


```
Command (m for help): g
Created a new GPT disklabel (GUID: 19234BAB-1862-294A-B7A0-16B0BF2969A6).

// /home用
Command (m for help): n
Partition number (1-128, default 1):
First sector (2048-156301454, default 2048):
Last sector, +/-sectors or +/-size{K,M,G,T,P} (2048-156301454, default 156301454): +20GiB

Created a new partition 1 of type 'Linux filesystem' and of size 20 GiB.

// /var用
Command (m for help): n
Partition number (2-128, default 2):
First sector (41945088-156301454, default 41945088):
Last sector, +/-sectors or +/-size{K,M,G,T,P} (41945088-156301454, default 156301454): +10GiB

Created a new partition 2 of type 'Linux filesystem' and of size 10 GiB.

// rootfs用
Command (m for help): n
Partition number (3-128, default 3):
First sector (62916608-156301454, default 62916608):
Last sector, +/-sectors or +/-size{K,M,G,T,P} (62916608-156301454, default 156301454):

Created a new partition 3 of type 'Linux filesystem' and of size 44.5 GiB.

Command (m for help): p
Disk /dev/sdc: 74.54 GiB, 80026361856 bytes, 156301488 sectors
Disk model: 0BEVE-00A0HT0
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: gpt
Disk identifier: 19234BAB-1862-294A-B7A0-16B0BF2969A6

Device        Start       End  Sectors  Size Type
/dev/sdc1      2048  41945087 41943040   20G Linux filesystem
/dev/sdc2  41945088  62916607 20971520   10G Linux filesystem
/dev/sdc3  62916608 156301454 93384847 44.5G Linux filesystem

Command (m for help): w
The partition table has been altered.
Calling ioctl() to re-read partition table.
Syncing disks.


// /home LABELつける
sudo mkfs.ext4 -L /home /dev/sdc1

mke2fs 1.45.4 (23-Sep-2019)
Creating filesystem with 5242880 4k blocks and 1310720 inodes
Filesystem UUID: b0b6a44b-b902-458a-9ae1-ac6ae1af1036
Superblock backups stored on blocks:
        32768, 98304, 163840, 229376, 294912, 819200, 884736, 1605632, 2654208,
        4096000

Allocating group tables: done
Writing inode tables: done
Creating journal (32768 blocks): done
Writing superblocks and filesystem accounting information: done


// /varラベルつける
sudo mkfs.ext4 -L /var /dev/sdc2

mke2fs 1.45.4 (23-Sep-2019)
Creating filesystem with 2621440 4k blocks and 655360 inodes
Filesystem UUID: 1f6f253c-08d5-468f-8892-87c592895ef6
Superblock backups stored on blocks:
        32768, 98304, 163840, 229376, 294912, 819200, 884736, 1605632

Allocating group tables: done
Writing inode tables: done
Creating journal (16384 blocks): done
Writing superblocks and filesystem accounting information: done


// 確認
sdc
├─sdc1    /home    9bddf318-8294-d845-bc41-bc19a61cc0d0
├─sdc2    /var     73dec024-6414-0040-a36f-59f0c8d38cd9
└─sdc3             152f1ff3-6451-9f43-9209-1c65cf07a940


// マウントして必要なファイルをコピー
mount /dev/sdc1 home
cp -a root/home/* home/

mount /dev/sdc2 var
cp -a root/var/* var/
える

// fstabを書き換える
proc                 /proc proc defaults         0 0
PARTUUID=6c586e13-01 /boot vfat defaults         0 2
LABEL=rootfs         /     ext4 defaults,noatime 0 1
LABEL=/home          /home ext4 defaults,noatime 0 2
LABEL=/var           /var  ext4 defaults,noatime 0 2ss
```

あとは、同じように設定していけば完了です。