Использование Puppet для удаления ключей SSH, которые не явно разрешены.

Вопрос или проблема

Я использую 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 всегда будет находиться в согласованном и безопасном состоянии.

Оцените материал
Добавить комментарий

Капча загружается...