cloud-init で実施する SSH サーバー設定まとめ


今まで 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

user-data
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つあります。

  1. GitHub / Launchpad から取得する
  2. 公開鍵を直接書く

1 の場合は

user-data
users:
- name: <ユーザー名>
  ssh_import_id: gh:<GitHub のユーザー名>
  (以下略)

2 の場合は

user-data
users:
- name: <ユーザー名>
  ssh_authorized_keys:
    - <ssh pub key 1>
    - <ssh pub key 2>
  (以下略)

のように書きます。

パスワード認証の禁止

SSH パスワード認証を禁止するには ssh_pwauth: no と書くだけで OK です。

user-data
ssh_pwauth: no

root ログインを禁止

disable_root という項目はありますが、これは /etc/ssh/sshd_config の PermitRootLogin を変更するものではありません。 SSH Modulessh_authorized_keys の項目を指定した場合に、その公開鍵について root ログインを制限するように設定するもののようです(ソースコードから確認、未検証)。

今回は /etc/ssh/sshd_config を書き換えたいので runcmd を使います。

user-data
runcmd:
- sed -i -e 's/^#PermitRootLogin prohibit-password/PermitRootLogin no/' /etc/ssh/sshd_config
- systemctl reload ssh

SSH のポート変更

ポート変更も Module は用意されていないので runcmd/etc/ssh/sshd_config を書き換えます。

user-data
runcmd:
- sed -i -e 's/^#Port 22/Port 22222/' /etc/ssh/sshd_config
- systemctl reload ssh

まとめ

上記の設定をひとつにまとめると以下になります。

user-data
#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 があるので、気になる人は見てみてください。

参考文献


  1. - defaultusers のリストに入れるとデフォルトの ubuntu ユーザーも作れます  

  2. https://askubuntu.com/questions/1365637/autoinstall-user-datas-users-section-does-not-work-at-all