今まで Ubuntu をヘッドレスインストールする時は、ネットワーク設定だけ済ませて、デフォルトの Ubuntu ユーザーでパスワード認証でいったんログインしてから /etc/ssh/sshd_config
書き換え……ということをやっていたのですが、 Raspberry Pi も増えてきてさすがに面倒になったので自動化してみました。
環境
- Raspberry Pi 4B
- Ubuntu 20.04
対象読者
- cloud-init を使って SSH 設定を自動化したい人
- (ユーザー作成)
- 公開鍵を設定 (~/.ssh/authorized_keys)
- SSH のパスワード認証を禁止 (PasswordAuthentication)
- SSH の root ログインを禁止 (PermitRootLogin)
- SSH のポートを変更
前提
cloud-init とは
cloud-init はマルチディストリビューション対応のクラウドインスタンスの初期化のツールです。名前の通りクラウドの VM を立ち上げるのに作られたものですが、 Raspberry Pi など非クラウド環境でも普通に使えます。
ファイルの先頭に #cloud-config
をつけるのがお約束。
Ubuntu におけるネットワーク設定
ヘッドレスインストール時に Wi-Fi を使用して接続したい場合や、固定 IP を指定したい場合は network-config ファイルを修正します。有線 LAN を使用して DHCP でつなぐ場合は必要ありません。
ちなみに筆者は有線 LAN + ルーターの DHCP サーバーで IP を固定しています(MAC アドレスが必要なので初回起動時は普通に DHCP の払い出し一覧から探してます )
形式は一般的な netplan の yaml なのでここでは説明を割愛します。
cloud-init によるユーザー作成
ubuntu では ubuntu という名前のユーザーがデフォルトで作成されますが、今回は ubuntu ユーザーを作らずに、別のユーザーを作ります1。筆者の場合はこんな感じの yaml になりました。
passwd に指定する値はパスワードそのものではなくパスワードのハッシュ値です。mkpasswd --method=SHA-512 --rounds=4096
のコマンドを打ち、パスワードを入力して出力された値を貼れば大丈夫です。
注意点としては passwd を指定する時は lock_passwd: false
にすること(デフォルトは true)。そうしないとパスワードでログインできません2。
users:
- name: <ユーザー名>
ssh_import_id: gh:<GitHub のユーザー名>
lock_passwd: false
passwd: $6$rounds=4096$sdAekclQbd/D6WW$6aeu3zScOXRQvFJFZRNs0n15e8bdd8SmQricBMudkvsskijM6OSzOdJ2OLG7L1aiqrVnkV88fSa4w3Gohlaaa.
shell: /bin/bash
sudo: ALL=(ALL) NOPASSWD:ALL
uid: 1000
参考
Users and Groups
Cloud config examples
SSH 設定
前置きが長くなりましたが本題に入ります。
公開鍵の設定
SSH でログインするための公開鍵を上で作成したユーザーの ~/.ssh/authorized_keys
に設定します。鍵の設定方法は2つあります。
- GitHub / Launchpad から取得する
- 公開鍵を直接書く
1 の場合は
users:
- name: <ユーザー名>
ssh_import_id: gh:<GitHub のユーザー名>
(以下略)
2 の場合は
users:
- name: <ユーザー名>
ssh_authorized_keys:
- <ssh pub key 1>
- <ssh pub key 2>
(以下略)
のように書きます。
パスワード認証の禁止
SSH パスワード認証を禁止するには ssh_pwauth: no
と書くだけで OK です。
ssh_pwauth: no
root ログインを禁止
disable_root
という項目はありますが、これは /etc/ssh/sshd_config
の PermitRootLogin を変更するものではありません。 SSH Module の ssh_authorized_keys
の項目を指定した場合に、その公開鍵について root ログインを制限するように設定するもののようです(ソースコードから確認、未検証)。
今回は /etc/ssh/sshd_config
を書き換えたいので runcmd
を使います。
runcmd:
- sed -i -e 's/^#PermitRootLogin prohibit-password/PermitRootLogin no/' /etc/ssh/sshd_config
- systemctl reload ssh
SSH のポート変更
ポート変更も Module は用意されていないので runcmd
で /etc/ssh/sshd_config
を書き換えます。
runcmd:
- sed -i -e 's/^#Port 22/Port 22222/' /etc/ssh/sshd_config
- systemctl reload ssh
まとめ
上記の設定をひとつにまとめると以下になります。
#cloud-config
# This is the user-data configuration file for cloud-init. By default this sets
# up an initial user called "ubuntu" with password "ubuntu", which must be
# changed at first login. However, many additional actions can be initiated on
# first boot from this file. The cloud-init documentation has more details:
#
# https://cloudinit.readthedocs.io/
# Set Passwords
# https://cloudinit.readthedocs.io/en/latest/topics/modules.html#set-passwords
ssh_pwauth: no
# Users and Groups
# https://cloudinit.readthedocs.io/en/latest/topics/modules.html#users-and-groups
users:
- name: <ユーザー名>
ssh_import_id: gh:<GitHub のユーザー名>
lock_passwd: false
passwd: $6$rounds=4096$sdAekclQbd/D6WW$6aeu3zScOXRQvFJFZRNs0n15e8bdd8SmQricBMudkvsskijM6OSzOdJ2OLG7L1aiqrVnkV88fSa4w3Gohlaaa.
shell: /bin/bash
sudo: ALL=(ALL) NOPASSWD:ALL
uid: 1000
# Runcmd
# https://cloudinit.readthedocs.io/en/latest/topics/modules.html#runcmd
runcmd:
- sed -i -e 's/^#Port 22/Port 14022/' /etc/ssh/sshd_config
- sed -i -e 's/^#PermitRootLogin prohibit-password/PermitRootLogin no/' /etc/ssh/sshd_config
- systemctl reload ssh
その他
今回は SSH に関係する項目をまとめましたが、他にもいろいろ module があるので、気になる人は見てみてください。
参考文献
-
- default
をusers
のリストに入れるとデフォルトの ubuntu ユーザーも作れます ↩ -
https://askubuntu.com/questions/1365637/autoinstall-user-datas-users-section-does-not-work-at-all ↩