Puppet: невозможно вручную создать сертификат и выдать запрос сертификата через API

Я потратил слишком много времени, пытаясь понять это сейчас, и мне действительно нужен указатель. Tl; dr в том, что мне нужно вручную создать сертификат на одном узле, а затем выдать запрос сертификата через API.

Согласно официальной документации, это должно быть довольно просто. Вот что я сделал.

Создать сертификат для myhost.foobar.local (из клиента)

$ puppet cert generate myhost.foobar.local

Генерация CSR из сертификата (от клиента)

$ openssl req -new -key /var/lib/puppet/ssl/private_keys/myhost.foobar.local.pem -subj "/CN=myhost.foobar.local" -out request.csr

Отправьте запрос на сертификат мастеру Puppet (от клиента)

API был открыт для удаленных вызовов API, поэтому мы можем выполнять вызов API с тестового узла. Однако я получаю только ошибку назад.

$ curl -k -X PUT -H "Content-Type: text/plain" --data-binary @request.csr https://puppetmaster:8140/production/certificate_request/no_key
Could not intern from s: not enough data

Другие звонки работают просто отлично, например:

$ curl -k -H "Accept: pson" https://puppetmaster:8140/production/certificate_statuses/all
[
  {
    "state" : "signed",
    "fingerprints" : {
      "default" : "5A:35:D2:19:59:C6:6E:B8:BE:64:54:FA:14:10:CE:FC:4A:C8:45:F6:DE:8E:7C:E9:2D:B0:5B:E0:5D:93:35:DD",
      "SHA256" : "5A:35:D2:19:59:C6:6E:B8:BE:64:54:FA:14:10:CE:FC:4A:C8:45:F6:DE:8E:7C:E9:2D:B0:5B:E0:5D:93:35:DD",
      "SHA1" : "04:13:AF:B9:CB:44:01:64:24:C9:E0:D6:F4:0D:60:41:52:77:EE:45",
      "SHA512" : "2C:97:11:B9:ED:38:00:1F:B0:7B:75:ED:4C:DB:B1:3E:3D:63:09:C1:38:E2:A3:4F:50:A4:FD:71:FF:55:94:C3:7A:0B:F6:D5:79:09:6D:53:39:B1:EC:C2:BF:DF:CD:9B:67:60:B9:9C:0C:82:51:E9:23:30:AA:33:AC:8B:E9:94"
    },
    "name" : "puppet.foobar.local",
    "dns_alt_names" : [
      "DNS:puppet",
      "DNS:puppet.foobar.local"
    ],
    "fingerprint" : "5A:35:D2:19:59:C6:6E:B8:BE:64:54:FA:14:10:CE:FC:4A:C8:45:F6:DE:8E:7C:E9:2D:B0:5B:E0:5D:93:35:DD"
  },
  {
    "state" : "signed",
    "fingerprints" : {
      "default" : "32:7B:B3:4E:BE:EB:66:21:E5:96:D0:7B:BA:BF:1D:FC:D5:90:E1:6F:52:6B:AB:CF:98:7E:2A:E3:48:00:A2:CF",
      "SHA256" : "32:7B:B3:4E:BE:EB:66:21:E5:96:D0:7B:BA:BF:1D:FC:D5:90:E1:6F:52:6B:AB:CF:98:7E:2A:E3:48:00:A2:CF",
      "SHA1" : "A4:17:D3:05:8A:72:BE:6C:C2:0C:FA:C4:8A:3B:6E:C4:29:90:4B:95",
      "SHA512" : "2D:C3:EE:7E:E3:39:99:C8:21:B8:97:E8:BF:FE:62:26:A8:B8:63:30:C9:F1:77:80:DB:FC:DF:B8:ED:1E:A2:6C:C2:F9:FE:5D:CA:17:D9:08:1E:EB:AA:AF:3D:99:A6:F9:3D:E6:86:A0:B3:3F:E9:EC:1C:7F:25:95:B5:D6:7C:51"
    },
    "name" : "965c252e48c3",
    "dns_alt_names" : [

    ],
    "fingerprint" : "32:7B:B3:4E:BE:EB:66:21:E5:96:D0:7B:BA:BF:1D:FC:D5:90:E1:6F:52:6B:AB:CF:98:7E:2A:E3:48:00:A2:CF"
  }
]

(отформатирован для удобства чтения)

Я не уверен, что я что-то здесь упускаю. Все другие вызовы API, кажется, работают нормально, включая подписывание и удаление / отзыв узлов. Это просто вызов запроса сертификата, который кажется сбойным. Возможно, я упускаю что-то очевидное.

Хозяин Марионеток запускает "3.7.2-1puppetlabs".

2 ответа

Решение

Разобрался с этими людьми в Puppet Labs. Правильный запрос подписи сертификата должен быть:

$ curl -k -X PUT -H "Content-Type: text/plain" --data-binary @request.csr https://puppetmaster:8140/production/certificate_request/hostname.foobar.local

Во-первых, я замечаю, что в ваших фрагментах командной строки ваша подсказка представляет собой '$'. Без сомнения, есть конфигурации марионеток, отличающиеся от моих, но мне нужно было запускать эти команды от имени пользователя root. Почти наверняка так в клиентской системе, где вы будете запускать Puppet от имени root. Если вы запускаете puppetmaster как что-то отличное от root, то, вероятно, вы выполняете команды CA puppet от имени этого пользователя.

Во-вторых, (и опять же может быть что-то другое в вашей настройке), мне никогда не нужно запускать команды openssl напрямую. Я делаю все с кукольными командами.

Что я делаю, это:

Во-первых, убедитесь, что полное доменное имя вашего клиента соответствует желаемому, поскольку оно будет использоваться при именовании сертификата. Проверить с hostname -f

В клиентской системе (как root):

puppet agent --test

Предполагая, что ключ еще не завершен, выше будет отображаться отпечаток сертификата, но если вам впоследствии потребуется отобразить его, используйте:

puppet agent --fingerprint --noop

На puppetmaster (как root):

puppet cert list

Проверьте отпечаток, затем выполните:

puppet cert sign [client's fqdn]

Если что-то пойдет не так, ищите различные ключи, сертификаты и запросы сертификатов в /var/lib/puppet/ssl (на клиенте) и /var/lib/puppet/ssl/ca (на главном сервере). По моему опыту макет говорит само за себя, и это безопасно, чтобы стереть вещи и ожидать, что они будут заново сгенерированы.

Я вижу, что вы спрашиваете конкретно об API, но вам действительно нужно обращаться к нему вручную? Если вы это сделаете, то следуйте приведенному выше рецепту, чтобы сгенерировать сертификаты, запросы на сертификаты и т. Д., А затем используйте команды openssl, чтобы просмотреть файлы, созданные в указанных мной местах, и сравнить с тем, что вы генерируете.

Если посмотреть на то, как puppet форматирует запрос API, я бы использовал ltrace для перехвата данных, передаваемых в / из вызовов библиотеки openssl. Кто-то, более знакомый с марионетками ruby ​​Framework, может вместо этого вставить туда отладочный код. (хотя на рабочем сервере ltrace намного безопаснее)

Другие вопросы по тегам