hashicorp / hashicorp/packer

Add Support to Generate Passwords

Open
#11,875 1 comment 18 reactions 0 assignees View on GitHub
enhancement
Dominant language
Go
Stars
15.8k
Forks
3.3k
PR merge metrics
PR metrics pending

Description

#### Community Note

* Please vote on this issue by adding a 👍 [reaction](https://blog.github.com/2016-03-10-add-reactions-to-pull-requests-issues-and-comments/) 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.

3. 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.

4. Keep secrets out of source control

5. 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
}
```

6. 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

Contributor guide

Open the contributing guide

Research direction

Start by locating Packer's existing data-source implementations and their tests, then review how configuration validation and sensitive outputs are handled. Done means a password-generating data source supports the requested length and alphabet constraints, applies the stated defaults and validation rules, and has coverage for those behaviors.

Written by the indexing model from the issue text.

Assessment

Tech stack
go
Domain
cli, security
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Needs clarification
Newbie friendliness
30/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.