■ 背景
最近、yomon8/raspberry-pi-imager |GitHub を参考にPacker + Docker + Ansible でラズパイイメージの自動生成を実装しています。
しかし困ったことに、最新のイメージは初回起動時にインタラクティブにユーザー登録やキーボード設定を行わないといけません。加えてデフォルトでオートログインが有効になっていたりと、サーバーとして起動することが考慮されていません。
起動後にこれらを設定するのは簡単ですが、イメージを自動生成する都合上、イメージの段階でこれらを設定をしなければなりません。
しかし、方法がどこにも載っておらず、、、かなり苦労したので、調べたことを残しておこうと思います。
■ 前準備
特に必要ないのですが、実際にファイルを見ながら理解したい方は↓でラズパイイメージをマウントするといいと思います。
■ デフォルトユーザーの設定
初回起動時にインタラクティブにユーザーを設定させないようにする設定です。
/boot/userconf
に ユーザー名:ハッシュ化パスワード
が設定されていると、初回起動時に自動でユーザー作成が行われます。
touch /boot/userconf
USER="xxxxxxxxx"
PASSWD="yyyyyyyy"
# パスワードをsha256でハッシュ化
HASHED_PASSWD="$(echo $PASSWD | openssl passwd -6 -stdin)"
# "ユーザー:ハッシュ化パスワード" を /boot/userconfに書き込みます
# [注意!] 末尾に改行を含んではいけません!
echo -n "${USER}:${HASHED_PASSWD} > /boot/userconf
■ オートログインの無効化
起動後だと /etc/systemd/system/getty@tty1.service.d/autologin.conf
を削除するだけで無効化できるのですが、イメージ段階で無効化する方法がなかなか見つからず、、、結局 autologin.conf
を生成している raspi-config
コマンドを書き換えました。
vim /usr/bin/raspi-config
do_boot_behaviour()
関数 (1377行目あたり)を書き換えます。
この関数は /usr/bin/cancel-rename
で raspi-config nonint do_boot_behaviour B2
のように呼び出され、強制的にオートログインが有効になる仕様です。
なので、B2の分岐で autologin.conf
が生成されないように修正します。
do_boot_behaviour() {
if [ "$INTERACTIVE" = True ]; then
BOOTOPT=$(whiptail --title "Raspberry Pi Software Configuration Tool (raspi-config)" --menu "Boot Options" $WT_HEIGHT $WT_WIDTH $WT_MENU_HEIGHT \
"B1 Console" "Text console, requiring user to login" \
"B2 Console Autologin" "Text console, automatically logged in as '$USER' user" \
"B3 Desktop" "Desktop GUI, requiring user to login" \
"B4 Desktop Autologin" "Desktop GUI, automatically logged in as '$USER' user" \
3>&1 1>&2 2>&3)
else
BOOTOPT=$1
true
fi
if [ $? -eq 0 ]; then
case "$BOOTOPT" in
B1*)
systemctl --quiet set-default multi-user.target
rm -f /etc/systemd/system/getty@tty1.service.d/autologin.conf
;;
B2*)
# *** *** *** 修正 (ここから) *** *** ***
# autologin.confが生成されないように修正
systemctl --quiet set-default multi-user.target
rm -f /etc/systemd/system/getty@tty1.service.d/autologin.conf
# systemctl --quiet set-default multi-user.target
# cat > /etc/systemd/system/getty@tty1.service.d/autologin.conf << EOF
#[Service]
#ExecStart=
#ExecStart=-/sbin/agetty --autologin $USER --noclear %I \$TERM
#EOF
# *** *** *** 修正 (ここまで) *** *** ***
;;
B3*)
# 略...
;;
B4*)
# 略...
;;
esac
systemctl daemon-reload
ASK_TO_REBOOT=1
fi
}
一応参考までに、 cancel-rename
は userconf-pi パッケージに含まれるリソースで、初回起動時にユーザーをリネームする機能のようです 。 (RPi-Distro/userconf-pi | GitHub)
※ cat /var/lib/dpkg/info/userconf-pi.list
に cancel-rename があります。
※ New package userconf-pi? | RaspberryPi
※ ちなみに、 userconf-pi をアンインストールしてしまうと、ログインプロンプトが表示されなくなって、ログインできなくなります。
#!/bin/bash
if [ "$(id -u)" != "0" ]; then
echo "Please run with 'sudo': sudo cancel-rename USER" >&2
exit 1
fi
if [ "$(raspi-config nonint get_boot_cli)" -ne 0 ]; then
if [ "$1" = "root" ] || ! getent passwd "$1" >/dev/null; then
echo "Please specify default user: sudo cancel-rename USER" >&2
exit 1
fi
# set up autologin
SUDO_USER="$1" raspi-config nonint do_boot_behaviour B4
# remove the autostart for the wizard
rm -f /etc/xdg/autostart/piwiz.desktop
# set up a self-deleting autostart to delete the wizard user
cat <<- EOF > /etc/xdg/autostart/deluser.desktop
[Desktop Entry]
Type=Application
Name=Delete Wizard User
NoDisplay=true
Exec=sh -c 'sudo userdel -r rpi-first-boot-wizard; sudo rm /etc/sudoers.d/010_wiz-nopasswd; sudo rm /etc/xdg/autostart/deluser.desktop'
EOF
else
SUDO_USER="$1" raspi-config nonint do_boot_behaviour B2
fi
systemctl --quiet disable userconfig
systemctl --quiet enable getty@tty1 --now --no-block
■ sshd有効化
デフォルトでsshdは無効です。
ラズパイでは初回起動時に /boot/ssh
というファイルが存在するとsshdが有効になります。
# sshd有効化
touch /boot/ssh
■ キーボード設定
jis配列のキーボードを使うための設定を行います。
touch /etc/default/keyboard
# KEYBOARD CONFIGURATION FILE
# Consult the keyboard(5) manual page.
XKBMODEL="pc105"
XKBLAYOUT="jp"
XKBVARIANT=""
XKBOPTIONS=""
BACKSPACE="guess"
■ WiFiの有効化
ラズパイのwifiは地域情報を設定しないと有効化できません。
※ 電波法とかの関連で無線規制区域を設定ファイルに書かないといけないらしいです。
wpa_supplicant.conf
に country=JP
を追記します。
touch /etc/wpa_supplicant/wpa_supplicant.conf
ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=netdev
update_config=1
country=JP
■ timezone設定
timezoneを Asia/Tokyo
に設定します。
cp /usr/share/zoneinfo/Asia/Tokyo /etc/localtime