2

I'm netboot installing Ubuntu focal and I have all the basic stuff working without issue. I use this template as the user-data yaml file and it makes the user, sets the password, and imports whatever ssh key I specify:

#cloud-config
autoinstall:
  apt:
    geoip: true
    preserve_sources_list: false
    primary:
    - arches: [amd64, i386]
      uri: http://us.archive.ubuntu.com/ubuntu
  identity: {
    hostname: <HOSTNAME>,
    password: <PWHASH>,
    realname: <USER>,
    username: <USER>
  }
  user-data:
    timezone: America/Los_Angeles
  keyboard: {layout: us, toggle: null, variant: ''}
  locale: en_US
  network:
    ethernets:
      mainif:
        match:
          macaddress: <MAC>
        set-name: eth0
      eth0:
        dhcp4: true
    version: 2
  ssh:
    allow-pw: true
    authorized-keys: [ <SSHKEY> ]
    install-server: true
  version: 1

I want to make it so that the user must change their password on first login.

Things I've tried:

  • Late command

    curtin in-target --target=/target --passwd --expire <USER>
    

    This fails because late commands apparently execute before users are created, even though the documentation says

    Shell commands to run after the install has completed successfully and any updates and packages installed, just before the system reboots.`

    The installer crashes, and I see in the crash report /var/crash/$date.unknown.crash that the command failed with exit status 1. Manually logging in, chrooting to /target, and trying the command confirms it, saying that user 'dan' doesn't exist, and it doesn't show up in /etc/passwd or /etc/shadow:

    snip of chroot /target, looking for any evidence of the specified user being created

  • Using chpasswd: {expire: True} in the identity section

    The installer crashes, saying that chpasswd is unexpected.

  • using bootcmd

    This is silently ignored

  • using a late command to write a cron in /target

     - /usr/bin/echo "@reboot root /usr/bin/passwd --expire dan && rm /etc/cron.d/update-pass" > /target/etc/cron.d/update-pass
    

    This does the job, but seems super fragile and extremely difficult to maintain.

Does auto-installer have built-in functionality for this that I haven't found?

1 Answer 1

1

Edit: I'm going to leave what I shared below, but I realized that I fixated on you wanting to change the user creation options when you really want to force the user to change password on first login.

It appears cloud-init does have an expire password option. Therefore, you can still use late-commands to modify the file /target/var/lib/cloud/seed/nocloud-net/user-data.

https://cloudinit.readthedocs.io/en/latest/topics/modules.html#set-passwords

By default, all users on the system will have their passwords expired (meaning that they will have to be reset the next time the user logs in)

Looking at the source, that statement only seems to apply to users where the password is specified with chpasswd. Appending configuration like the following to user-data might force the user to change password on next login

chpasswd:
    list: |
        <USER>:<PWHASH>

Original Post below

You'll have to do something like use late-commands to call sed to modify the file /target/var/lib/cloud/seed/nocloud-net/user-data.

The server installer, subiquity, takes your autoinstall configuration and creates cloud-init configuration to be used on first boot. However, subiquity only supports a subset of what cloud-init can actually do. Looking at the source code, you can see where subiquity actually hard-codes this setting to 'lock_passwd': False,

https://github.com/canonical/subiquity/blob/a76581cd2b973b55e55c6ac05b5bf47168493140/subiquity/models/subiquity.py#L197

You are unable to change the user in late-commands because the user does not exist yet. The user gets created on first boot by cloud-init.

This snippet is untested, but autoinstall configuration like this should do what you want

late-commands:
    - sed -ie 's/lock.passwd.*/lock_passwd: true,/' /target/var/lib/cloud/seed/nocloud-net/user-data

Minor detail. Depending on the subiquity version, the user-data file may contain lock_passwd or lock-passwd. The regex lock.passwd should match both and cloud-init wants lock_passwd. There was a bug in the initial 20.04 release - https://github.com/canonical/subiquity/pull/784

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .