前提条件
- VirutalBoxで仮想マシンを作り、Debian GNU/Linux 12 (bookwarm) をインストールする
- EFIはOFF
- HDDは1つで、単一のルートパーティションで構成
- ネットワークアダプタは2つで、1つ目がNAT、2つ目が固定IP用のホストオンリーアダプタ
- インストールメディアは netinst版のISOファイルを使用している
手順概要
- preseed.cfg を作成
- インストールDVDのルートに配置する
- インストーラー起動時のカーネルパラメーターで自動インストールを指定する
1. preseed.cfg を作成
公式ガイドはこちら。
preseed.cfgは部分的でもよく、インストーラーが聞いてくる項目のうちここで指定しているものだけがスキップされ、preseed.cfgで指定していないものは通常通りにインストーラーが入力を求めてくる。
なので、preseed.cfgを作る際はインストーラーの問合せ項目ごとに1項目書いては実際にテストして、うまくスキップされたら次の項目を書いて、と進めていくと一つずつ進められる。
また、一度普通に(手動で)インストールしてから下記コマンドで preseed.cfg を出力して、指定する値の参考にするといい。
sudo apt install debconf-utils
sudo debconf-get-selections --installer
自分が作った preseed.cfg の全体像はこんな感じ。
#_preseed_V1
# 言語・場所の選択
d-i	debian-installer/locale	string	ja_JP.UTF-8
# キーボードの設定
d-i	keyboard-configuration/xkb-keymap	select	jp
# タイムゾーン
d-i	time/zone	string	Asia/Tokyo
# ネットワークの設定
d-i	netcfg/get_hostname	string	(ホスト名)
d-i	netcfg/get_domain	string	(ドメイン名)
d-i	netcfg/choose_interface	select	ens0p17
# ユーザとパスワードのセットアップ
d-i	passwd/root-login	boolean	false
d-i	passwd/user-fullname	string	(ユーザー名:フルネーム)
d-i	passwd/username	string	(ユーザー名:ログイン名)
d-i	passwd/user-default-groups	string	(ユーザーが所属するグループ名)
# sudo apt -y install whois pwgen && mkpasswd -m sha-512 -S $(pwgen -ns 16 1)
d-i	passwd/user-password-crypted	password	(上記のコマンドでパスワードハッシュを生成して記載)
# ディスクのパーティショニング
d-i	partman-auto/disk	string	/dev/sda
d-i	partman-auto/method	string	regular
d-i	partman-auto/choose_recipe	select	atomic
d-i	partman-partitioning/confirm_write_new_label	boolean	true
d-i	partman/choose_partition	select	finish
d-i	partman/confirm	boolean	true
d-i	partman/confirm_nooverwrite	boolean	true
# パッケージマネージャの設定
d-i	apt-setup/cdrom/set-first	boolean	false
d-i	mirror/country	string	JP
d-i	mirror/http/hostname	string	deb.debian.org
d-i	mirror/https/hostname	string	deb.debian.org
d-i	mirror/http/mirror	select	deb.debian.org
d-i	mirror/https/mirror	select	deb.debian.org
d-i	mirror/http/proxy	string
d-i	mirror/https/proxy	string
# パッケージ利用調査
d-i	popularity-contest/participate	boolean	true
# ソフトウェアの選択
tasksel	tasksel/first	multiselect	standard, ssh-server
d-i	pkgsel/upgrade	select	safe-upgrade
# ブートローダのインストール
d-i	grub-installer/only_debian	boolean	true
d-i	grub-installer/bootdev	string	/dev/sda
# インストールの完了メッセージを表示しない
d-i	finish-install/reboot_in_progress	note
# インストール完了後、再起動せずに電源をオフにするかどうか
d-i	debian-installer/exit/poweroff	boolean	false
# インストール後に実行するコマンド
d-i	preseed/late_command	string	in-target sh -c '\
: "ネットワーク設定"; \
echo "auto enp0s8"               >/etc/network/interfaces.d/enp0s8; \
echo "iface enp0s8 inet static" >>/etc/network/interfaces.d/enp0s8; \
echo "   address 192.168.56.10" >>/etc/network/interfaces.d/enp0s8; \
echo "   netmask 255.255.255.0" >>/etc/network/interfaces.d/enp0s8; \
: "起動設定"; \
echo "GRUB_TIMEOUT=1" >/etc/default/grub.d/local.cfg; \
update-grub; \
: "sshサーバーの設定"; \
echo "PermitRootLogin no"               >/etc/ssh/sshd_config.d/local.conf; \
echo "PasswordAuthentication no"       >>/etc/ssh/sshd_config.d/local.conf; \
echo "KbdInteractiveAuthentication no" >>/etc/ssh/sshd_config.d/local.conf; \
: "ssh公開鍵を登録"; \
mkdir /home/(ユーザー名:ログイン名)/.ssh; \
chmod 0700 /home/(ユーザー名:ログイン名)/.ssh; \
echo "(ssh公開キー)" >/home/(ユーザー名:ログイン名)/.ssh/authorized_keys; \
chmod 0600 /home/(ユーザー名:ログイン名)/.ssh/authorized_keys; \
: "alias を有効化"; \
echo "alias ll='\''ls -l'\''" >/home/(ユーザー名:ログイン名)/.bash_aliases; \
echo "alias la='\''ls -a'\''" >>/home/(ユーザー名:ログイン名)/.bash_aliases; \
echo "alias lA='\''ls -A'\''" >>/home/(ユーザー名:ログイン名)/.bash_aliases; \
echo "alias lla='\''ls -la'\''" >>/home/(ユーザー名:ログイン名)/.bash_aliases; \
echo "alias llA='\''ls -lA'\''" >>/home/(ユーザー名:ログイン名)/.bash_aliases; \
: "ホームディレクトリに作成したファイルの所有者を設定"; \
chown -R (ユーザー名:ログイン名):(ユーザー名:ログイン名) /home/(ユーザー名:ログイン名); \
'
1-1. ヘッダ
#_preseed_V1
preseed.cfg では先頭にこの行が必須。
1-2. 言語・場所の選択
d-i	debian-installer/locale	string	ja_JP.UTF-8
英語の場合は en_US.UTF-8 を指定する。
1-3. キーボードの設定
d-i	keyboard-configuration/xkb-keymap	select	jp
日本語キーボードを指定。
1-4. タイムゾーン
d-i	time/zone	string	Asia/Tokyo
実はロケールで ja_JP.UTF-8 を指定すると、この項目を指定しなくても勝手にこのタイムゾーンが設定されるが、 en_US.UTF-8 を指定するとインストーラーでUS/*のタイムゾーンの選択画面が表示された。
ロケール中に複数のタイムゾーンが含まれる地域では指定必須らしい。
そうでなくても指定して害になるものではないので、とりあえず常に指定しておけばいいだろう。
ちなみにGUIの選択画面でタイムゾーンをUTCにする方法は見あたらなかったが、preseedでは
d-i	time/zone	string	UTC
これで行ける。
1-5. ホスト名とドメイン名
d-i	netcfg/get_hostname	string	(ホスト名)
d-i	netcfg/get_domain	string	(ドメイン名)
1-6. ネットワークの設定
d-i	netcfg/choose_interface	select	auto
これで、先頭の(?)ネットワークアダプタでDHCP接続をするように設定してくれる。
ネットワークアダプタが複数あって特定のものを明示したい場合は netcfg/choose_interface でデバイス名を指定してあげればいい。
d-i	netcfg/choose_interface	select	ens0p17
DHCPを利用せずに静的アドレスを指定する場合は
d-i	netcfg/choose_interface	select	enp0s17
d-i	netcfg/disable_dhcp	boolean	true
d-i	netcfg/confirm_static	boolean	true
d-i	netcfg/get_ipaddress	string	172.16.2.10
d-i	netcfg/get_netmask	string	255.255.0.0
d-i	netcfg/get_gateway	string	172.16.2.1
d-i	netcfg/get_nameservers	string	192.168.1.1 8.8.8.8
ネームサーバーが複数ある場合、スペース区切りで指定する。
preseed の netcfg/*では、複数のネットワークアダプタを設定することはできないようだ。
VirtualBoxでは、ネットワークアダプタ1でインターネット接続用のNATを指定して、ネットワークアダプタ2で固定IP接続用のホストオンリーアダプタを使う、というのが鉄板だと思うが、そういうことをしたい場合はここではNATアダプタのみ設定し、固定IP用アダプタはあとで説明する preseed/late_command で指定するのがよさそう。
1-7. ユーザとパスワードのセットアップ
d-i	passwd/root-login	boolean	false
d-i	passwd/user-fullname	string	(ユーザー名:フルネーム)
d-i	passwd/username	string	(ユーザー名:ログイン名)
d-i	passwd/user-default-groups	string	(ユーザーが所属するグループ名)
d-i	passwd/user-password-crypted	password	(パスワードハッシュ)
最初に下記でrootログインを禁止している。
d-i	passwd/root-login	boolean	false
rootログインを許可する場合は、代わりに下記でパスワードを指定する。
d-i passwd/root-password-crypted password (パスワードハッシュ)
パスワードハッシュは、下記のコマンドで生成する。
mkpasswd -m sha-512 -S $(pwgen -ns 16 1)
もしmkpasswdかpwgenがインストールされていない場合は、下記のコマンドでインストールすること。
sudo apt -y install whois pwgen
以降は一般ユーザーの設定。
d-i	passwd/user-fullname	string	(ユーザー名:フルネーム)
d-i	passwd/username	string	(ユーザー名:ログイン名)
d-i	passwd/user-default-groups	string	(ユーザーが所属するグループ名)
d-i	passwd/user-password-crypted	password	(パスワードハッシュ)
(ユーザー名:フルネーム)はスペースを含んでもいいが、(ユーザー名:ログイン名)はダメ。
(ユーザーが所属するグループ名)は、複数のグループ名をスペース区切りで指定する。
Debianでは初期状態でsudoグループに所属するユーザーがsudo可能となっているので、rootログインを禁止する場合はここにsudoを含めておくか、 preseed/late_command 等でこのユーザーを sudoers に追加するなどして、sudoを利用できる状態にしておくこと。
(パスワードハッシュ) の作り方は passwd/root-password-crypted と同じ。
インストール時点で一般ユーザーを作成しない場合、上記の代わりに下記を指定する。
d-i passwd/make-user boolean false
当然ながら、rootログイン禁止と併用するとインストール後のシステムに誰も入れなくなるので注意すること。
1-8. ディスクのパーティショニング
d-i	partman-auto/disk	string	/dev/sda
d-i	partman-auto/method	string	regular
d-i	partman-auto/choose_recipe	select	atomic
d-i	partman-partitioning/confirm_write_new_label	boolean	true
d-i	partman/choose_partition	select	finish
d-i	partman/confirm	boolean	true
d-i	partman/confirm_nooverwrite	boolean	true
ここでは、下記を指定している。
- /dev/sda をパーティショニングする
- 基本パーティションを利用(regular)。ほかに、LVMパーティションを利用(lvm)、LVM暗号化を利用(crypto) を選択できる
- 全てのファイルを1つのパーティションに含める(atomic)。ほかに、/homeパーティションを分ける(home)、/home、/var、/tmpパーティションを分ける (multi) を選択できる
- 確認画面を表示しない
カスタムパーティションを作成する場合は記述が複雑になるが、インストーラーで選択できる自動パーティショニングならこれだけ。
1-8. パッケージマネージャの設定
d-i	apt-setup/cdrom/set-first	boolean	false
d-i	mirror/country	string	JP
d-i	mirror/http/hostname	string	deb.debian.org
d-i	mirror/https/hostname	string	deb.debian.org
d-i	mirror/http/mirror	select	deb.debian.org
d-i	mirror/https/mirror	select	deb.debian.org
d-i	mirror/http/proxy	string
d-i	mirror/https/proxy	string
自分はインストールに netinst 版ISOを使っているので、インストールはすべてネットから取得する。
DVD版やBD版で大量のパッケージがメディアに入っている場合はもしかしたら設定が変わるかもしれない。
apt-setup/cdrom/set-first では、追加のインストールメディアをスキャンするかどうかの選択。
複数枚版のCD/DVDでインストールする場合は有用なのかも?
mirror/country はミラーサイトの国を選択。
mirror/*/hostname と mirror/*/mirror でインストール元のサイト名を選択している。
mirror/*/proxy は接続にプロキシを指定する場合の設定だが、プロキシ不要でも空の設定を入れておく必要がある。
1-9. パッケージ利用調査
d-i	popularity-contest/participate	boolean	true
パッケージの利用調査に参加する場合はtrue、しない場合はfalseを指定する。
1-10. ソフトウェアの選択
tasksel	tasksel/first	multiselect	standard, ssh-server
d-i	pkgsel/upgrade	select	safe-upgrade
デスクトップなどを選択するならここ。
この項目だけ質問の所有者(各行先頭の項目)が d-i ではなく tasksel になるので注意すること。
pkgsel/upgrade では、debootstrap後にパッケージをアップグレードするかどうかを指定する。
none、safe-upgrade、full-upgrade のいずれかを指定する。
その意味の詳細について公式ガイドに見当たらないが、たぶんここのaptitudeのコマンドと同じ意味だと思う。
1-11. 追加のパッケージをインストール
d-i pkgsel/include string net-tools
これは省略可能。書かなくても自動インストールは最後まで進む。
ただ、追加したいパッケージがあればここにスペース区切りで列挙できる。
ちなみにnet-tools は netstat や route などネットワーク関連のコマンドを含むパッケージ。
1-12. ブートローダのインストール
d-i	grub-installer/only_debian	boolean	true
d-i	grub-installer/bootdev	string	/dev/sda
これからインストールする Debian GNU/Linux がシステムで唯一のOSで、ディスクが1つだけのBIOSシステムならこのように指定する。
EFIの場合はインストール先デバイスがちょっと変わると思う。
1-13. インストールの完了メッセージを表示しない
これを指定しないとインストール終了画面で止まる。
d-i	finish-install/reboot_in_progress	note
1-14. インストール完了後、再起動せずに電源をオフにするかどうか
こちらは省略可能で、省略した場合はインストール終了後に自動で再起動する。
d-i	debian-installer/exit/poweroff	boolean	false
上記のように false を指定した場合も同様。
true を指定すると、再起動せずに電源断となる。
1-15. インストール後に実行するコマンド
これも省略可能。インストール終了後に実行したい処理を記載する。
d-i	preseed/late_command	string	in-target sh -c '\
: "ネットワーク設定"; \
echo "auto enp0s8"               >/etc/network/interfaces.d/enp0s8; \
echo "iface enp0s8 inet static" >>/etc/network/interfaces.d/enp0s8; \
echo "   address 192.168.56.10" >>/etc/network/interfaces.d/enp0s8; \
echo "   netmask 255.255.255.0" >>/etc/network/interfaces.d/enp0s8; \
: "起動設定"; \
echo "GRUB_TIMEOUT=1" >/etc/default/grub.d/local.cfg; \
update-grub; \
: "sshサーバーの設定"; \
echo "PermitRootLogin no"               >/etc/ssh/sshd_config.d/local.conf; \
echo "PasswordAuthentication no"       >>/etc/ssh/sshd_config.d/local.conf; \
echo "KbdInteractiveAuthentication no" >>/etc/ssh/sshd_config.d/local.conf; \
: "ssh公開鍵を登録"; \
mkdir /home/(ユーザー名:ログイン名)/.ssh; \
chmod 0700 /home/(ユーザー名:ログイン名)/.ssh; \
echo "(ssh公開キー)" >/home/(ユーザー名:ログイン名)/.ssh/authorized_keys; \
chmod 0600 /home/(ユーザー名:ログイン名)/.ssh/authorized_keys; \
: "alias を有効化"; \
echo "alias ll='\''ls -l'\''" >/home/(ユーザー名:ログイン名)/.bash_aliases; \
echo "alias la='\''ls -a'\''" >>/home/(ユーザー名:ログイン名)/.bash_aliases; \
echo "alias lA='\''ls -A'\''" >>/home/(ユーザー名:ログイン名)/.bash_aliases; \
echo "alias lla='\''ls -la'\''" >>/home/(ユーザー名:ログイン名)/.bash_aliases; \
echo "alias llA='\''ls -lA'\''" >>/home/(ユーザー名:ログイン名)/.bash_aliases; \
: "ホームディレクトリに作成したファイルの所有者を設定"; \
chown -R (ユーザー名:ログイン名):(ユーザー名:ログイン名) /home/(ユーザー名:ログイン名); \
'
ここはあくまでインストーラーの世界で、インストール先のファイルシステムは /target ディレクトリにマウントされているため、/ を起点としたファイルパスを指定したり普通に apt install を実行してもインストール先システムに正しく反映されない。
このため、/target ディレクトリにchrootするか、 in-target や apt-install といったコマンドを利用する必要がある。
また、すべてのコマンドは preseed/late_command の値として書く必要があるが、preseedの一つの項目は原則1行で書かなければならない。
ただし、行末の \ で継続行を指定できるので、これを利用して複数行で記載することができる。
また、Linux Shellも行末の \ で継続行となるので、この2つの性質を同時に満足させる書き方をする必要がある。
例えば、
cat <<<EOS >/etc/network/interface.d/enp0s8
auto enp0s8
iface enp0s8 inet static
   address 192.168.56.10
   netmask 255.255.255.0
EOS
シェルで複数行の出力をする場合、自分はこういう書き方が好きだが、末尾に継続行が置けないためpreseedではNGとなる。
また、コメントを # で書くと継続行が使えなくなるので、シェルの組み込みコマンド : を利用している。これは任意の数の引数を取る何もしないコマンドで、こういうときのコメント代わりに便利。
自分の場合、何度も in-target を書くのが嫌だしリダイレクトも面倒なので、in-target sh -c で全部まとめて指定している。
上記でやっていることは、2つ目のネットワークアダプタで固定IPを設定
: "ネットワーク設定"; \
echo "auto enp0s8"               >/etc/network/interfaces.d/enp0s8; \
echo "iface enp0s8 inet static" >>/etc/network/interfaces.d/enp0s8; \
echo "   address 192.168.56.10" >>/etc/network/interfaces.d/enp0s8; \
echo "   netmask 255.255.255.0" >>/etc/network/interfaces.d/enp0s8; \
起動時のGRUB画面のタイムアウトを1秒に変更(せっかちさん向け)
: "起動設定"; \
echo "GRUB_TIMEOUT=1" >/etc/default/grub.d/local.cfg; \
update-grub; \
SSHサーバーでルートログインとパスワード認証を禁止
: "sshサーバーの設定"; \
echo "PermitRootLogin no"               >/etc/ssh/sshd_config.d/local.conf; \
echo "PasswordAuthentication no"       >>/etc/ssh/sshd_config.d/local.conf; \
echo "KbdInteractiveAuthentication no" >>/etc/ssh/sshd_config.d/local.conf; \
SSHパスワード認証を禁止するなら必須となる公開キーの準備
: "ssh公開鍵を登録"; \
mkdir /home/(ユーザー名:ログイン名)/.ssh; \
chmod 0700 /home/(ユーザー名:ログイン名)/.ssh; \
echo "(ssh公開キー)" >/home/(ユーザー名:ログイン名)/.ssh/authorized_keys; \
chmod 0600 /home/(ユーザー名:ログイン名)/.ssh/authorized_keys; \
お好みで alias を登録
ここは sh -c '...' の中の世界なので、シングルクォートのエスケープが必要 (' → '\'')
echo "alias ll='\''ls -l'\''" >/home/(ユーザー名:ログイン名)/.bash_aliases; \
echo "alias la='\''ls -a'\''" >>/home/(ユーザー名:ログイン名)/.bash_aliases; \
echo "alias lA='\''ls -A'\''" >>/home/(ユーザー名:ログイン名)/.bash_aliases; \
echo "alias lla='\''ls -la'\''" >>/home/(ユーザー名:ログイン名)/.bash_aliases; \
echo "alias llA='\''ls -lA'\''" >>/home/(ユーザー名:ログイン名)/.bash_aliases; \
ここまででホームディレクトリに配置したファイルのオーナーがrootになっているので、まとめて変更
: "ホームディレクトリに作成したファイルの所有者を設定"; \
chown -R (ユーザー名:ログイン名):(ユーザー名:ログイン名) /home/(ユーザー名:ログイン名); \
以上で preseed.cfg 完成となる。
2. インストールDVDのルートに配置する
これが面倒だからと、公式ガイドでは http によるpreseed.cfg配布をお勧めしている。
でも、VirtualBoxでは仮想ISOが使えるから超簡単。
まずはこんなテキストファイルを用意する。
--iprt-iso-maker-file-marker-bourne-sh 4c62d9cb-520f-4b28-b38e-76203f360a58
--import-iso=C:/Users/(ユーザー名)/Downloads/Debian/debian-12.6.0-amd64-netinst.iso
/preseed.cfg=preseed.cfg
拡張子が .viso ならファイル名は何でもいい。
--iprt-iso-maker-file-marker-bourne-sh で指定するGUIDは一応毎回変えているが、変えなくても問題なさそう。これはよくわかってない。
--import-iso で指定するパスは適宜修正すること。
/preseed.cfg=preseed.cfg
この = の前の /preseed.cfg が仮想ISOファイル中のファイルパスで、=の後の preseed.cfg がそこに配置する実ファイル。絶対パスまたは作成するvisoファイルの位置からの相対パスで指定する。
ここでは debian.viso と preseed.cfg を同じフォルダに置いているので、ファイル名のみで指定できている。
仮想ISO内のファイル名と実ファイル名が一致している必要はないので、ローカルでは preseed-test1.cfg とかでもvisoの中では preseed.cfg で参照できる。
この visoファイルを、普通のISOファイルと同じように仮想マシンの光学ドライブにマウントすればいい。
そうすると、マウントした仮想環境からは debian-12.6.0-amd64-netinst.iso のルートに preseed.cfg が追加されたように見える。
ちなみに、--import-iso で指定したisoファイルに存在するファイルと同じパスを指定するとエラーになる。
既存ファイルを上書きするような動作になれば便利なんだけど。
<2025/2/10追記>
既存ファイルを上書きできたw
--iprt-iso-maker-file-marker-bourne-sh 4c62d9cb-520f-4b28-b38e-76203f360a58
--import-iso=C:/Users/(ユーザー名)/Downloads/Debian/debian-12.6.0-amd64-netinst.iso
/preseed.cfg=preseed.cfg
/boot/grub/grub.cfg=:must-remove:
/boot/grub/grub.cfg=grub.cfg
上の4行目のような感じで =:must-remove: とやるとファイルを削除できるっぽい。
その後に同パスでファイルを指定してあげれば、上書き配置ができる(5行目)。
この grub.cfg で、インストールDVDの中のオリジナルをベースに timeout を変更したりカーネルパラメータ  auto=true fiile=/cdrom/preseed.cfg を追加してあげれば、次の工程で起動時にブートパラメータを手作業で追加する必要がなくなる。
3. インストーラー起動時のカーネルパラメーターで自動インストールを指定する
仮想環境を起動して、GRUB画面が表示されたらTABキーを押下。

ブートパラメータが編集できるようになるので、--- の前に下記を挿入
auto=true fiile=/cdrom/preseed.cfg

この時点では英字キーボードとして認識されているので、日本語配列とは = のキーが違うことに注意。
auto=true により、自動インストールを有効にする。
file=/cdrom/preseed.cfg で preseed.cfg のパスを示す。
つまり、preseed.cfg のファイル名は別にこれでなくてもよさそう。
インストーラー上でインストールCDは /cdrom 以下にマウントされるので、ここがCDのルートとなっている。
file= というのは正式には preseed/file= だが、このように省略できる。
この状態でEnterを押すと、入力なしでシステムがインストールされ、debian-installer/exit/poweroff の設定次第でリブート or シャットダウンされる。
いじょ。
