Skip to content

Add Support to Generate Passwords #11875

@bloudraak

Description

@bloudraak

Community Note

  • Please vote on this issue by adding a 👍 reaction to the original issue to help the community and maintainers prioritize this request
  • Please do not leave "+1" or other comments that do not add relevant new information or questions, they generate extra noise for issue followers and do not help prioritize the request
  • If you are interested in working on this issue or have submitted a pull request, please leave a comment

Description

Provide a data source that will generate a reasonably complex password for use during the Packer build.

Using a random complex computer-generated temporary password can improve the security of the overall infrastructure, and make systems less prone to be compromised later on.

Here's a method using PowerShell to generate a random complex passwords:

function New-Password {
    param (
        [int] $length = 16,
        [string] $alphabet = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()_+<>,.?/:;~`-='
    )
    $rng = New-Object System.Security.Cryptography.RNGCryptoServiceProvider
    $bytes = New-Object byte[]($length)
    $rng.GetBytes($bytes)
    $value = [system.numerics.BigInteger]::Abs([bigint]$bytes)
    $result = New-Object char[]($length)

    $base = $alphabet.Length
    for ($i = 0 ; $i -lt $length ; $i++) {
        $remainder = $value % $base
        $value = $value / $base
        $result[$i] = $alphabet[$remainder]
    }
    return (-join $result)
}

The code above shows demonstrates how to generate a password using a single alphabet of a fixed length, which is mostly satisfactory.

In order to add more entropy, generate passwords of different lengths.

In order to better support problematic requirements, you can support specific alphabets, allowing you to specify which symbols are allowed, which numeric characters are allowed and so forth.

Use Case(s)

  1. When installing any operating system from ISO that requires the root or administrator password to be set, generate a temporary password, pass it to the build commands, or as parameters to provisioners. For example, in Ubuntu, the temporary password will allow the root or ubuntu user to be configured, and in the same process be used to create an Ansible user, after which the admin or root account is disabled, or deleted.

  2. In scenarios where passwords are treated as "need-to-know", Packer can lessen the burden of the organization by generating new passwords whenever a new template is created, exporting it, and allowing a subsequent process to store it in a secret manager, where other processes can pick it up when interacting with the templates.

  3. Keep secrets out of source control

  4. Minimize the configuration of CI/CD systems, by generating temporary secrets.

Potential configuration

This can be implemented using a function or as a data source. I'd suggest using a data source so that one can specify alphabets and complex configuration with reasonable defaults.

  1. Create a complex password 32-64 characters in length, with symbols and alpha numeric characters. The minimum number of symbols and numbers are at least 10% of the length of the chars.

    data "password" "example" {}
    
  2. Create a complex password with custom lengths

    data "password" "example" {
        min = 16
        max = 24
    }
    
  3. Some systems are a bit more pandantic in terms of what makes a valid password, for example specifying which symbols are required and the minimum.

    data "password" "example" {
        min = 8
        max = 15
        alphabet = "@#$%abcdefghjkmnpqrstvwxyzABCDEFGHIJKLMNOPQRSTUWXYZ23456789"
     }
    

In some cases you may have a need to control the alphabets and components of the password, so it may look something as follows:

data "password" "example" {
  min = 8
  max = 15
  alphabet {
     characters = "@#$%"
     min = 2 // need at least two symbols
  }
   alphabet {
     characters = "abcdefghjkmnpqrstvwxyzABCDEFGHIJKLMNOPQRSTUWXYZ"
  }
  alphabet {
     characters = "23456789"
     min = 2 // net at least two numeric characters
  }
}

or if you don't care about how many symbols and whatnot is in the password:

data "password" "example" {
  min = 32
  max = 64
  alphabet {
     value = "@#$%abcdefghjkmnpqrstvwxyzABCDEFGHIJKLMNOPQRSTUWXYZ23456789"
  }
}

Some validation rules:

  • The sum of minimums of the alphabets cannot exceed the max of the password
  • The sum of the maximums of the alphabets cannot exceed the max of the password, not be less than the minimum length of the password.
  • The default minimum of an alphabet would be 2
  • The default minimum length of a password would be 32
  • The default maximum length of a password would be 64
  • The default alphabet would be "01234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ`~@#$%^&*()_-+={[}]:;<>,.?/". Note that characters like quotes and other chars probably needs to be excluded to ease automation, so the password can injected in places, without causing syntax errors.

Potential References

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions