Skip to content

Add support for modern keyrings #1128

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 36 commits into from
Oct 27, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
6cef41f
Add apt::keyring defined type which creates modern-style keyrings
jorhett May 2, 2023
2fb1b17
Update README.md
Ramesh7 Sep 29, 2023
bfc2c7f
Update README.md
Ramesh7 Sep 29, 2023
5c122e3
Update README.md
Ramesh7 Sep 29, 2023
e8e98e1
Update README.md
Ramesh7 Sep 29, 2023
d7155fb
Update README.md
Ramesh7 Sep 29, 2023
e423dbf
Update README.md
Ramesh7 Sep 29, 2023
ee8d03a
Update manifests/source.pp
Ramesh7 Sep 29, 2023
6525552
Update manifests/source.pp
Ramesh7 Sep 29, 2023
19e479b
Update manifests/source.pp
Ramesh7 Sep 29, 2023
da06d9a
Update manifests/source.pp
Ramesh7 Sep 29, 2023
3c8e3cf
Update manifests/source.pp
Ramesh7 Sep 29, 2023
f8ddb8c
Update manifests/init.pp
Ramesh7 Sep 29, 2023
ca1bcce
Update manifests/keyring.pp
Ramesh7 Sep 29, 2023
4c17cf5
Update manifests/keyring.pp
Ramesh7 Sep 29, 2023
f6eee34
Update manifests/keyring.pp
Ramesh7 Sep 29, 2023
ff60961
Update manifests/keyring.pp
Ramesh7 Sep 29, 2023
73b27de
Update manifests/keyring.pp
Ramesh7 Sep 29, 2023
94f392c
Update manifests/source.pp
Ramesh7 Sep 29, 2023
9e38a7c
Update manifests/source.pp
Ramesh7 Sep 29, 2023
fd32f03
Regenerating REFERENCE.md file
Ramesh7 Sep 29, 2023
62a3ddc
Update README.md
Ramesh7 Oct 2, 2023
ca1d98a
Added acceptance for keyring
praj1001 Oct 18, 2023
35c4736
Fixing rubocops
praj1001 Oct 18, 2023
9f49af5
Changed implementation for variable declaration
praj1001 Oct 18, 2023
dedcfc2
Changed puppetlabs spec helper version
praj1001 Oct 20, 2023
1abcb69
Added file location just an extra check
praj1001 Oct 21, 2023
072b412
Deleting the file
praj1001 Oct 24, 2023
63883a8
removed tabs
praj1001 Oct 24, 2023
2ee7f97
indent fix
praj1001 Oct 24, 2023
6832736
fixed closing braces
praj1001 Oct 24, 2023
795dcb2
Added spec for comparing contents of keyring file
praj1001 Oct 25, 2023
faacdf0
Rubocop fixed
praj1001 Oct 25, 2023
9074993
Fixed import and list keys options
praj1001 Oct 25, 2023
ea37970
retry on error matching
praj1001 Oct 25, 2023
9ada844
PR comments resolution
praj1001 Oct 26, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ group :development do
gem "voxpupuli-puppet-lint-plugins", '~> 4.0', require: false
gem "facterdb", '~> 1.18', require: false
gem "metadata-json-lint", '~> 3.0', require: false
gem "puppetlabs_spec_helper", '~> 6.0', require: false
gem "puppetlabs_spec_helper", '~> 7.0', require: false
gem "rspec-puppet-facts", '~> 2.0', require: false
gem "codecov", '~> 0.2', require: false
gem "dependency_checker", '~> 1.0.0', require: false
Expand Down
38 changes: 38 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,28 @@ include apt

### Add GPG keys

You can fetch GPG keys via HTTP, Puppet URI, or local filesystem. The key can be in GPG binary format, or ASCII armored, but the filename should have the appropriate extension (`.gpg` for keys in binary format; or `.asc` for ASCII armored keys).

#### Fetch via HTTP

```puppet
apt::keyring { 'puppetlabs-keyring.gpg':
source => 'https://apt.puppetlabs.com/keyring.gpg',
}
```

#### Fetch via Puppet URI

```puppet
apt::keyring { 'puppetlabs-keyring.gpg':
source => 'puppet:///modules/my_module/local_puppetlabs-keyring.gpg',
}
```

Alternatively `apt::key` can be used.

**Warning** `apt::key` is deprecated in the latest Debian and Ubuntu releases. Please use apt::keyring instead.

**Warning:** Using short key IDs presents a serious security issue, potentially leaving you open to collision attacks. We recommend you always use full fingerprints to identify your GPG keys. This module allows short keys, but issues a security warning if you use them.

Declare the `apt::key` defined type:
Expand Down Expand Up @@ -184,6 +206,22 @@ apt::source { 'puppetlabs':
}
```

### Adding name and source to the key parameter of apt::source, which then manages modern apt gpg keyrings

The `name` parameter of key hash should contain the filename with extension (such as `puppetlabs.gpg`).

```puppet
apt::source { 'puppetlabs':
comment => 'Puppet8',
location => 'https://apt.puppetlabs.com/',
repos => 'puppet8',
key => {
'name' => 'puppetlabs.gpg',
'source' => 'https://apt.puppetlabs.com/keyring.gpg',
},
}
```

<a id="configure-apt-from-hiera"></a>

### Configure Apt from Hiera
Expand Down
133 changes: 128 additions & 5 deletions REFERENCE.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@

* [`apt::conf`](#apt--conf): Specifies a custom Apt configuration file.
* [`apt::key`](#apt--key): Manages the GPG keys that Apt uses to authenticate packages.
* [`apt::keyring`](#apt--keyring): Manage GPG keyrings for apt repositories
* [`apt::mark`](#apt--mark): Manages apt-mark settings
* [`apt::pin`](#apt--pin): Manages Apt pins. Does not trigger an apt-get update run.
* [`apt::ppa`](#apt--ppa): Manages PPA repositories using `add-apt-repository`. Not supported on Debian.
Expand Down Expand Up @@ -73,6 +74,7 @@ The following parameters are available in the `apt` class:
* [`proxy_defaults`](#-apt--proxy_defaults)
* [`sources`](#-apt--sources)
* [`keys`](#-apt--keys)
* [`keyrings`](#-apt--keyrings)
* [`ppas`](#-apt--ppas)
* [`pins`](#-apt--pins)
* [`settings`](#-apt--settings)
Expand Down Expand Up @@ -239,6 +241,14 @@ Creates new `apt::key` resources. Valid options: a hash to be passed to the crea

Default value: `$apt::params::keys`

##### <a name="-apt--keyrings"></a>`keyrings`

Data type: `Hash`

Hash of `apt::keyring` resources.

Default value: `{}`

##### <a name="-apt--ppas"></a>`ppas`

Data type: `Hash`
Expand Down Expand Up @@ -624,6 +634,101 @@ Passes additional options to `apt-key adv --keyserver-options`.

Default value: `$apt::key_options`

### <a name="apt--keyring"></a>`apt::keyring`

Manage GPG keyrings for apt repositories

#### Examples

##### Download the puppetlabs apt keyring

```puppet
apt::keyring { 'puppetlabs-keyring.gpg':
source => 'https://apt.puppetlabs.com/keyring.gpg',
}
```

##### Deploy the apt source and associated keyring file

```puppet
apt::source { 'puppet8-release':
location => 'http://apt.puppetlabs.com',
repos => 'puppet8',
key => {
name => 'puppetlabs-keyring.gpg',
source => 'https://apt.puppetlabs.com/keyring.gpg'
}
}
```

#### Parameters

The following parameters are available in the `apt::keyring` defined type:

* [`keyring_dir`](#-apt--keyring--keyring_dir)
* [`keyring_filename`](#-apt--keyring--keyring_filename)
* [`keyring_file`](#-apt--keyring--keyring_file)
* [`keyring_file_mode`](#-apt--keyring--keyring_file_mode)
* [`source`](#-apt--keyring--source)
* [`content`](#-apt--keyring--content)
* [`ensure`](#-apt--keyring--ensure)

##### <a name="-apt--keyring--keyring_dir"></a>`keyring_dir`

Data type: `Stdlib::Absolutepath`

Path to the directory where the keyring will be stored.

Default value: `'/etc/apt/keyrings'`

##### <a name="-apt--keyring--keyring_filename"></a>`keyring_filename`

Data type: `String[1]`

Optional filename for the keyring. It should also contain extension along with the filename.

Default value: `$name`

##### <a name="-apt--keyring--keyring_file"></a>`keyring_file`

Data type: `Stdlib::Absolutepath`

File path of the keyring.

Default value: `"${keyring_dir}/${keyring_filename}"`

##### <a name="-apt--keyring--keyring_file_mode"></a>`keyring_file_mode`

Data type: `Stdlib::Filemode`

File permissions of the keyring.

Default value: `'0644'`

##### <a name="-apt--keyring--source"></a>`source`

Data type: `Optional[Stdlib::Filesource]`

Source of the keyring file. Mutually exclusive with 'content'.

Default value: `undef`

##### <a name="-apt--keyring--content"></a>`content`

Data type: `Optional[String[1]]`

Content of the keyring file. Mutually exclusive with 'source'.

Default value: `undef`

##### <a name="-apt--keyring--ensure"></a>`ensure`

Data type: `Enum['present','absent']`

Ensure presence or absence of the resource.

Default value: `'present'`

### <a name="apt--mark"></a>`apt::mark`

Manages apt-mark settings
Expand Down Expand Up @@ -925,6 +1030,20 @@ apt::source { 'puppetlabs':
}
```

##### Download key behaviour to handle modern apt gpg keyrings. The `name` parameter in the key hash should be given with

```puppet
extension. Absence of extension will result in file formation with just name and no extension.
apt::source { 'puppetlabs':
location => 'http://apt.puppetlabs.com',
comment => 'Puppet8',
key => {
'name' => 'puppetlabs.gpg',
'source' => 'https://apt.puppetlabs.com/keyring.gpg',
},
}
```

#### Parameters

The following parameters are available in the `apt::source` defined type:
Expand Down Expand Up @@ -1001,9 +1120,12 @@ Default value: `{}`

Data type: `Optional[Variant[String, Hash]]`

Creates a declaration of the apt::key defined type. Valid options: a string to be passed to the `id` parameter of the `apt::key`
defined type, or a hash of `parameter => value` pairs to be passed to `apt::key`'s `id`, `server`, `content`, `source`, `weak_ssl`,
and/or `options` parameters.
Creates an `apt::keyring` in `/etc/apt/keyrings` (or anywhere on disk given `filename`) Valid options:
* a hash of `parameter => value` pairs to be passed to `file`: `name` (title), `content`, `source`, `filename`

The following inputs are valid for the (deprecated) `apt::key` defined type. Valid options:
* a string to be passed to the `id` parameter of the `apt::key` defined type
* a hash of `parameter => value` pairs to be passed to `apt::key`: `id`, `server`, `content`, `source`, `weak_ssl`, `options`

Default value: `undef`

Expand All @@ -1012,6 +1134,7 @@ Default value: `undef`
Data type: `Optional[Stdlib::AbsolutePath]`

Absolute path to a file containing the PGP keyring used to sign this repository. Value is used to set signed-by on the source entry.
This is not necessary if the key is installed with `key` param above.
See https://wiki.debian.org/DebianRepository/UseThirdParty for details.

Default value: `undef`
Expand All @@ -1030,8 +1153,8 @@ Default value: `undef`
Data type: `Optional[String]`

Tells Apt to only download information for specified architectures. Valid options: a string containing one or more architecture names,
separated by commas (e.g., 'i386' or 'i386,alpha,powerpc'). Default: undef (if unspecified, Apt downloads information for all architectures
defined in the Apt::Architectures option).
separated by commas (e.g., 'i386' or 'i386,alpha,powerpc').
(if unspecified, Apt downloads information for all architectures defined in the Apt::Architectures option)

Default value: `undef`

Expand Down
10 changes: 10 additions & 0 deletions manifests/init.pp
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,9 @@
# @param keys
# Creates new `apt::key` resources. Valid options: a hash to be passed to the create_resources function linked above.
#
# @param keyrings
# Hash of `apt::keyring` resources.
#
# @param ppas
# Creates new `apt::ppa` resources. Valid options: a hash to be passed to the create_resources function linked above.
#
Expand Down Expand Up @@ -159,6 +162,7 @@
Apt::Proxy $proxy = $apt::params::proxy,
Hash $sources = $apt::params::sources,
Hash $keys = $apt::params::keys,
Hash $keyrings = {},
Hash $ppas = $apt::params::ppas,
Hash $pins = $apt::params::pins,
Hash $settings = $apt::params::settings,
Expand Down Expand Up @@ -347,6 +351,12 @@
if $keys {
create_resources('apt::key', $keys)
}
# manage keyrings if present
$keyrings.each |$key, $data| {
apt::keyring { $key:
* => $data,
}
}
# manage ppas if present
if $ppas {
create_resources('apt::ppa', $ppas)
Expand Down
74 changes: 74 additions & 0 deletions manifests/keyring.pp
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
# @summary Manage GPG keyrings for apt repositories
#
# @example Download the puppetlabs apt keyring
# apt::keyring { 'puppetlabs-keyring.gpg':
# source => 'https://apt.puppetlabs.com/keyring.gpg',
# }
# @example Deploy the apt source and associated keyring file
# apt::source { 'puppet8-release':
# location => 'http://apt.puppetlabs.com',
# repos => 'puppet8',
# key => {
# name => 'puppetlabs-keyring.gpg',
# source => 'https://apt.puppetlabs.com/keyring.gpg'
# }
# }
#
# @param keyring_dir
# Path to the directory where the keyring will be stored.
#
# @param keyring_filename
# Optional filename for the keyring. It should also contain extension along with the filename.
#
# @param keyring_file
# File path of the keyring.
#
# @param keyring_file_mode
# File permissions of the keyring.
#
# @param source
# Source of the keyring file. Mutually exclusive with 'content'.
#
# @param content
# Content of the keyring file. Mutually exclusive with 'source'.
#
# @param ensure
# Ensure presence or absence of the resource.
#
define apt::keyring (
Stdlib::Absolutepath $keyring_dir = '/etc/apt/keyrings',
String[1] $keyring_filename = $name,
Stdlib::Absolutepath $keyring_file = "${keyring_dir}/${keyring_filename}",
Stdlib::Filemode $keyring_file_mode = '0644',
Optional[Stdlib::Filesource] $source = undef,
Optional[String[1]] $content = undef,
Enum['present','absent'] $ensure = 'present',
) {
ensure_resource('file', $keyring_dir, { ensure => 'directory', mode => '0755', })
if $source and $content {
fail("Parameters 'source' and 'content' are mutually exclusive")
} elsif ! $source and ! $content {
fail("One of 'source' or 'content' parameters are required")
}

case $ensure {
'present': {
file { $keyring_file:
ensure => 'file',
mode => $keyring_file_mode,
owner => 'root',
group => 'root',
source => $source,
content => $content,
}
}
'absent': {
file { $keyring_file:
ensure => $ensure,
}
}
default: {
fail("Invalid 'ensure' value '${ensure}' for apt::keyring")
}
}
}
Loading