Вопрос или проблема
Я использую Puppet для распределения SSH-ключей, следующим образом:
ssh_authorized_key { "[email protected]":
ensure => present,
key => 'xxxx',
type => 'ssh-rsa',
user => 'deploy',
}
Файл ~/.ssh/authorized_keys в итоге содержит смесь ключей из разных классов, что является желаемым результатом. Однако, если ключ был добавлен вручную в $HOME/.ssh/authorized_keys, Puppet оставит его на месте. Есть ли способ всегда удалять любой ключ, который не был явно определён в манифесте?
У меня версия Puppet 2.7.1.
Начиная с Puppet 3.6 теперь возможно удалять неуправляемые SSH авторизованные ключи через тип user
. Например,
user { 'nick':
ensure => present,
purge_ssh_keys => true,
}
Вместо использования ресурсов ssh_authorized_key
, я решил определить ресурс authorized_keys
, который принимает список всех SSH-ключей для одного пользователя. Определение выглядит так:
define authorized_keys ($sshkeys, $ensure = "present", $home="") {
# Эта строка позволяет задать домашний каталог по умолчанию на основе переменной $title.
# Если $home пуст, используется значение по умолчанию.
$homedir = $home ? {'' => "/home/${title}", default => $home}
file {
"${homedir}/.ssh":
ensure => "directory",
owner => $title,
group => $title,
mode => 700,
require => User[$title];
"${homedir}/.ssh/authorized_keys":
ensure => $ensure,
owner => $ensure ? {'present' => $title, default => undef },
group => $ensure ? {'present' => $title, default => undef },
mode => 600,
require => File["${homedir}/.ssh"],
content => template("authorized_keys.erb");
}
}
$ssh_keys
параметр принимает все необходимые ключи в виде списка. Шаблон authorized_keys.erb
выглядит следующим образом:
# УВЕДОМЛЕНИЕ: Этот файл автоматически сгенерирован Puppet и не должен изменяться
<% sshkeys.each do |key| -%>
<%= key %>
<% end -%>
Использование
user {'mikko':
...
}
authorized_keys {'mikko':
sshkeys => [
'ssh-rsa XXXXXXYYYYYYYYYZZZZZZZZZ [email protected]',
'ssh-rsa XXXXXXZZZZZZZZZHHHHHHHHH [email protected]',
],
}
Добавлять SSH-ключи условно (например, в разных классах) также легко, благодаря оператору +>
Puppet:
Authorized_keys <| title == 'mikko' |> {
sshkeys +> 'ssh-rsa ASDFASDFASDFASDF [email protected]'
}
С этим методом у пользователя никогда не будет ключей, которые не указаны явно в конфигурации Puppet. Строка ключа используется в authorized_keys точно так же, как она есть, так что добавление опций и ограничений не составляет труда.
Мне было бы приятно услышать, если кто-то применял этот метод успешно!
Вы должны иметь возможность сделать это, используя метатип resources. Например:
resources { 'ssh_authorized_key': noop => true, purge => true, }
Установка noop => true,
предотвращает удаление. Вместо этого, puppet будет сообщать о том, что было бы удалено. Если это то, что вам нужно, удалите оператор noop.
Идеальный синтаксис для выполнения операций с неуправляемыми ресурсами находится в обсуждении.
ПРАВКА: Как упоминалось в комментариях, этот ответ не работает.
В Puppet Forge был опубликован модуль под лицензией Apache License, Version 2.0, который предлагает эту возможность.
Тем не менее, он полагается на Puppet concat вместо шаблонов.
https://github.com/nightfly19/puppet-ssh_keys/tree/master/manifests
Вместо того, чтобы передавать массив ключей в качестве параметра, вы определяете отдельные записи для каждого ключа.
Другой подход, чем у Mikko, но тот же конечный результат.
Программное обеспечение вставьте описание изображения здесь
Уберите опцию explicit
Ответ или решение
Удаление неразрешённых SSH-ключей с использованием Puppet
Когда речь идет о развертывании управляемых конфигураций SSH через Puppet, важно не только добавлять одобренные SSH-ключи, но и контролировать появление неуправляемых ключей в файле ~/.ssh/authorized_keys
. В этой статье мы рассмотрим подходы к удалению SSH-ключей, которые не были явно определены в манифестах Puppet.
Введение
Puppet является мощным инструментом для управления конфигурациями, позволяя администраторам систем легко управлять ключами доступа для пользователей. Важно, чтобы система всегда оставалась в согласованном состоянии, что требует удаления любых неразрешённых изменений.
Использование ресурса ssh_authorized_key
Стандартный метод для добавления SSH-ключей в Puppet — это использование ресурса ssh_authorized_key
. Пример:
ssh_authorized_key { "user@example.com":
ensure => present,
key => 'xxxx',
type => 'ssh-rsa',
user => 'deploy',
}
Тем не менее, данный подход не предоставляет возможности автоматически удалять ключи, которые были добавлены вручную в файл authorized_keys
.
Метод с использованием ресурса user
и purging
Начиная с версии Puppet 3.6, вы можете использовать параметр purge_ssh_keys
в ресурсе user
, который позволяет удалить неразрешённые ключи:
user { 'username':
ensure => present,
purge_ssh_keys => true,
}
Этот метод эффективен, однако требует обновления Puppet до более новой версии.
Определение ресурса authorized_keys
Также существует метод, при котором вы можете создать собственный ресурс, позволяющий удобно управлять добавлением и удалением SSH-ключей. Ниже представлен пример определения ресурса authorized_keys
, который принимает массив ключей:
define authorized_keys($sshkeys, $ensure = "present", $home = "") {
$homedir = $home ? { '' => "/home/${title}", default => $home }
file { "${homedir}/.ssh":
ensure => "directory",
owner => $title,
group => $title,
mode => 700,
require => User[$title],
}
file { "${homedir}/.ssh/authorized_keys":
ensure => $ensure,
owner => $ensure ? { 'present' => $title, default => undef },
group => $ensure ? { 'present' => $title, default => undef },
mode => 600,
require => File["${homedir}/.ssh"],
content => template("authorized_keys.erb"),
}
}
Шаблон authorized_keys.erb
Шаблон для authorized_keys
будет выглядеть следующим образом:
# ВНИМАНИЕ: Этот файл сгенерирован Puppet и не должен изменяться вручную
<% sshkeys.each do |key| -%>
<%= key %>
<% end -%>
Теперь, если пользователь добавляет открытые ключи, не указанные в манифесте, они будут удаляться при следующем применении конфигурации Puppet.
Упрощение добавления ключей
Также вы можете использовать оператор +>
для добавления SSH-ключей условно:
authorized_keys <| title == 'username' |> {
sshkeys +> 'ssh-rsa YOUR_NEW_KEY'
}
Таким образом, можно легко управлять добавлением ключей в зависимости от условий.
Заключение
Управление SSH-ключами через Puppet значительно упрощается, если вы используете ресурсы, способные удалять неразрешённые изменения. Эта практика обеспечивает соответствие вашей системе требованиям безопасности, исключая возможность уязвимостей из-за неуправляемых ключей. Предложенные методы и ресурсы позволяют гибко управлять ключами, а также обеспечивают полный контроль над доступом пользователей к вашему серверу.
Используя описанные подходы, вы можете быть уверены, что ваша конфигурация SSH всегда будет находиться в согласованном и безопасном состоянии.