やりたいこと
SSHのパスワード認証方式を禁止したい。それをcloud-initで設定したい。
前提条件
- 機種: Raspberry Pi 2 Model B
- OSイメージ: ubuntu-18.04.2-preinstalled-server-armhf+raspi2.img.xz
- https://wiki.ubuntu.com/ARM/RaspberryPi からダウンロードできる。
- Raspberry Pi 2用にUbuntuがインストールされた状態のディスクイメージ。これをSDカードに焼くと、そのまま起動できる。
うまくいかなかったこと
cloud-initが /etc/ssh/sshd_config
で PasswordAuthentication no
と設定してくれることを期待して、
/etc/cloud/cloud.cfg.d/999_my.cfg
を次のように設定した。
ssh_pwauth: False
ところが、初回起動時に PasswordAuthentication yes
と設定されてしまった。
/var/log/cloud-init.log
においてもその形跡が確認できる(option PasswordAuthentication updated no -> yes
)。
$ fgrep -5 PasswordAuthentication /var/log/cloud-init.log 2019-04-28 09:18:11,706 - helpers.py[DEBUG]: Running config-set-passwords using lock (<FileLock using file '/var/lib/cloud/instances/nocloud/sem/config_set_passwords'>) 2019-04-28 09:18:11,710 - cc_set_passwords.py[DEBUG]: Changing password for ['ubuntu']: 2019-04-28 09:18:11,712 - util.py[DEBUG]: Running command ['chpasswd'] with allowed return codes [0] (shell=False, capture=True) 2019-04-28 09:18:11,948 - util.py[DEBUG]: Reading from /etc/ssh/sshd_config (quiet=False) 2019-04-28 09:18:11,951 - util.py[DEBUG]: Read 3262 bytes from /etc/ssh/sshd_config 2019-04-28 09:18:11,955 - ssh_util.py[DEBUG]: line 56: option PasswordAuthentication updated no -> yes 2019-04-28 09:18:11,957 - util.py[DEBUG]: Writing to /etc/ssh/sshd_config - wb: [644] 3263 bytes 2019-04-28 09:18:11,962 - util.py[DEBUG]: Running command ['service', 'ssh', 'restart'] with allowed return codes [0] (shell=False, capture=True) 2019-04-28 09:18:12,226 - cc_set_passwords.py[DEBUG]: Restarted the ssh daemon. 2019-04-28 09:18:12,228 - handlers.py[DEBUG]: finish: modules-config/config-set-passwords: SUCCESS: config-set-passwords ran successfully 2019-04-28 09:18:12,229 - stages.py[DEBUG]: Running module grub-dpkg (<module 'cloudinit.config.cc_grub_dpkg' from '/usr/lib/python3/dist-packages/cloudinit/config/cc_grub_dpkg.py'>) with frequency once-per-instance
原因
/etc/cloud/cloud.cfg.d/999_my.cfg
よりもデータソース"NoCloud"の設定の方が優先されたため。
Ubuntuをインストール済みのディスクイメージには /var/lib/cloud/seed/nocloud-net/user-data
と /var/lib/cloud/seed/nocloud-net/meta-data
が存在していた。
$ cat var/lib/cloud/seed/nocloud-net/user-data #cloud-config password: ubuntu chpasswd: ubuntu ssh_pwauth: True
$ cat var/lib/cloud/seed/nocloud-net/meta-data instance_id: cloud-image
var/lib/cloud/seed/nocloud-net/user-data
には ssh_pwauth: True
と記載されており、この設定が優先されたため、 PasswordAuthentication yes
に書き換えられてしまった。
解決策
データソースリストから"NoCloud"を消して"None"だけにする。
そのために、 /etc/cloud/cloud.cfg.d/999_my.cfg
の先頭に次の行を追記する。
datasource_list: [None]
この修正を加えたSDカードを改めて作った。初回起動時のログを見ると PasswordAuthentication
は no
のままになっていることがわかる。
ubuntu@raspi:~$ fgrep PasswordAuthentication /var/log/cloud-init.log 2019-04-28 15:26:15,960 - ssh_util.py[DEBUG]: line 56: option PasswordAuthentication already set to no 2019-04-28 15:26:15,961 - cc_set_passwords.py[DEBUG]: No need to restart ssh service, PasswordAuthentication not updated.
参考情報
/etc/cloud/
のファイル構成
ubuntu@raspi:/etc/cloud$ tree . ├── build.info ├── cloud.cfg ├── cloud.cfg.d │ ├── 05_logging.cfg │ ├── 90_dpkg.cfg │ ├── 99-fake_cloud.cfg │ └── README └── templates ├── chef_client.rb.tmpl ├── chrony.conf.debian.tmpl ├── chrony.conf.fedora.tmpl ├── chrony.conf.opensuse.tmpl ├── chrony.conf.rhel.tmpl ├── chrony.conf.sles.tmpl ├── chrony.conf.ubuntu.tmpl ├── hosts.debian.tmpl ├── hosts.freebsd.tmpl ├── hosts.redhat.tmpl ├── hosts.suse.tmpl ├── ntp.conf.debian.tmpl ├── ntp.conf.fedora.tmpl ├── ntp.conf.opensuse.tmpl ├── ntp.conf.rhel.tmpl ├── ntp.conf.sles.tmpl ├── ntp.conf.ubuntu.tmpl ├── resolv.conf.tmpl ├── sources.list.debian.tmpl ├── sources.list.ubuntu.tmpl └── timesyncd.conf.tmpl
/etc/cloud/cloud.cfg
の中身
# The top level settings are used as module # and system configuration. # A set of users which may be applied and/or used by various modules # when a 'default' entry is found it will reference the 'default_user' # from the distro configuration specified below users: - default # If this is set, 'root' will not be able to ssh in and they # will get a message to login instead as the default $user disable_root: true # This will cause the set+update hostname module to not operate (if true) preserve_hostname: false # Example datasource config # datasource: # Ec2: # metadata_urls: [ 'blah.com' ] # timeout: 5 # (defaults to 50 seconds) # max_wait: 10 # (defaults to 120 seconds) # The modules that run in the 'init' stage cloud_init_modules: - migrator - seed_random - bootcmd - write-files - growpart - resizefs - disk_setup - mounts - set_hostname - update_hostname - update_etc_hosts - ca-certs - rsyslog - users-groups - ssh # The modules that run in the 'config' stage cloud_config_modules: # Emit the cloud config ready event # this can be used by upstart jobs for 'start on cloud-config'. - emit_upstart - snap - snap_config # DEPRECATED- Drop in version 18.2 - ssh-import-id - locale - set-passwords - grub-dpkg - apt-pipelining - apt-configure - ubuntu-advantage - ntp - timezone - disable-ec2-metadata - runcmd - byobu # The modules that run in the 'final' stage cloud_final_modules: - snappy # DEPRECATED- Drop in version 18.2 - package-update-upgrade-install - fan - landscape - lxd - puppet - chef - mcollective - salt-minion - rightscale_userdata - scripts-vendor - scripts-per-once - scripts-per-boot - scripts-per-instance - scripts-user - ssh-authkey-fingerprints - keys-to-console - phone-home - final-message - power-state-change # System and/or distro specific settings # (not accessible to handlers/transforms) system_info: # This will affect which distro class gets used distro: ubuntu # Default user name + that default users groups (if added/used) default_user: name: ubuntu lock_passwd: True gecos: Ubuntu groups: [adm, audio, cdrom, dialout, dip, floppy, lxd, netdev, plugdev, sudo, video] sudo: ["ALL=(ALL) NOPASSWD:ALL"] shell: /bin/bash # Automatically discover the best ntp_client ntp_client: auto # Other config here will be given to the distro class and/or path classes paths: cloud_dir: /var/lib/cloud/ templates_dir: /etc/cloud/templates/ upstart_dir: /etc/init/ package_mirrors: - arches: [i386, amd64] failsafe: primary: http://archive.ubuntu.com/ubuntu security: http://security.ubuntu.com/ubuntu search: primary: - http://%(ec2_region)s.ec2.archive.ubuntu.com/ubuntu/ - http://%(availability_zone)s.clouds.archive.ubuntu.com/ubuntu/ - http://%(region)s.clouds.archive.ubuntu.com/ubuntu/ security: [] - arches: [arm64, armel, armhf] failsafe: primary: http://ports.ubuntu.com/ubuntu-ports security: http://ports.ubuntu.com/ubuntu-ports search: primary: - http://%(ec2_region)s.ec2.ports.ubuntu.com/ubuntu-ports/ - http://%(availability_zone)s.clouds.ports.ubuntu.com/ubuntu-ports/ - http://%(region)s.clouds.ports.ubuntu.com/ubuntu-ports/ security: [] - arches: [default] failsafe: primary: http://ports.ubuntu.com/ubuntu-ports security: http://ports.ubuntu.com/ubuntu-ports ssh_svcname: ssh
/etc/cloud/cloud.cfg.d/99-fake_cloud.cfg
の中身
# configure cloud-init for NoCloud datasource_list: [ NoCloud, None ]
ここでデータソースが"NoCloud"、"None"の順に定義されている。