Назад | Перейти на главную страницу

Марионетка: невозможно вручную создать сертификат и отправить запрос сертификата через 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.

Разобрался вместе с хорошими ребятами из 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, то, вероятно, вы выполняете команды puppet CA от имени этого пользователя.

Во-вторых (и опять же, в вашей настройке может быть что-то другое), мне никогда не нужно запускать команды 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, чтобы просмотреть файлы, созданные в указанных мною местах, и сравнить с тем, что вы создаете.

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