Vault PKI: различия между версиями

Материал из noname.com.ua
Перейти к навигацииПерейти к поиску
 
(не показаны 94 промежуточные версии этого же участника)
Строка 3: Строка 3:
 
[[Категория:Vault]]
 
[[Категория:Vault]]
 
[[Категория:Linux]]
 
[[Категория:Linux]]
  +
[[Категория:Kubernetes the hard way v2]]
  +
 
=Vault PKI=
 
=Vault PKI=
  +
OpenSSL это очень просто (нет)
  +
<BR>
  +
 
Развертывание PKI на основе Vault
 
Развертывание PKI на основе Vault
   
Строка 10: Строка 15:
   
 
=PKI=
 
=PKI=
  +
  +
Логика работы (кратко)
  +
* Создается несколько инстансов PKI внутри одного процесса Vault (для большей безопастности)
  +
* Корневой сертефикат выписывается корневым PKI
  +
** Кроме прочего - он может быть удален из волта, закрыт в сейфе и т п для безопастности так как используется только для создания промежуточного СА
  +
* этот сертификат (он НЕ является секретным) распространяется по всем нодам и используется для проверки
  +
* этим сертификатом подписвается промежуточный CA
  +
* промежуточный CA подписывает клиентские сертификаты
  +
  +
Кроме того можно удлинить эту цепочку используя уже готовый СА и промежуточный СА и импортировав их в Vault (но примера тут нет - я не делал)
  +
 
==Включить PKI для корневого сертификата==
 
==Включить PKI для корневого сертификата==
 
<PRE>
 
<PRE>
Строка 19: Строка 35:
 
</PRE>
 
</PRE>
 
==Создание корневого сертефиката (CA)==
 
==Создание корневого сертефиката (CA)==
  +
===Конфигурация Vault===
 
 
* ВАЖНО: Тип определяет будет ли показан ключ от сертификата. В случае <B> internal</B> ключ показа не будет и сертификат можно будет использовать только в Vault
 
* ВАЖНО: Тип определяет будет ли показан ключ от сертификата. В случае <B> internal</B> ключ показа не будет и сертификат можно будет использовать только в Vault
   
Строка 36: Строка 52:
 
ttl="262800h" > pki-root-ca.json
 
ttl="262800h" > pki-root-ca.json
 
</PRE>
 
</PRE>
  +
* ttl="262800h" - 30 лет
 
 
* В теории возможно использовать пре-созданный CA или даже цепочку - смотреть тут: https://groups.google.com/g/vault-tool/c/y4IcgiLBG4c
 
* В теории возможно использовать пре-созданный CA или даже цепочку - смотреть тут: https://groups.google.com/g/vault-tool/c/y4IcgiLBG4c
   
  +
===Просмотр результата===
 
Результат работы команды (длинный вывод пропущен):
 
Результат работы команды (длинный вывод пропущен):
 
<PRE>
 
<PRE>
Строка 60: Строка 77:
   
 
Корневой сертефикат самоподписаный. Поля certificate и issuing_ca полностью совпадают.
 
Корневой сертефикат самоподписаный. Поля certificate и issuing_ca полностью совпадают.
  +
  +
===Подготовка файлов с сертефикатом и ключем===
  +
<PRE>
  +
cat pki-root-ca.json | jq -r .data.certificate > rootCA.pem
  +
</PRE>
  +
  +
<PRE>
  +
cat pki-root-ca.json | jq -r .data.issuing_ca > rootCA_issuing_ca.pem
  +
</PRE>
  +
  +
<PRE>
  +
cat pki-root-ca.json | jq -r .data.private_key > rootCA_private_key.pem
  +
</PRE>
  +
<PRE>
  +
openssl x509 -in rootCA.pem -text -noout
  +
</PRE>
  +
<PRE>
  +
Certificate:
  +
Data:
  +
Version: 3 (0x2)
  +
Serial Number:
  +
05:55:c5:9b:20:91:66:86:96:42:84:bd:66:9a:c1:70:28:8d:bf:82
  +
Signature Algorithm: sha256WithRSAEncryption
  +
Issuer: C = Ukraine, L = Kharkov, street = app. 131 + street = Lui Pastera St. 322, postalCode = 61172, O = Home Network, OU = IT, CN = Root Certificate Authority for Home Network
  +
Validity
  +
Not Before: Oct 10 12:58:00 2021 GMT
  +
Not After : Oct 3 12:58:27 2051 GMT
  +
Subject: C = Ukraine, L = Kharkov, street = app. 131 + street = Lui Pastera St. 322, postalCode = 61172, O = Home Network, OU = IT, CN = Root Certificate Authority for Home Network
  +
Subject Public Key Info:
  +
Public Key Algorithm: rsaEncryption
  +
RSA Public-Key: (2048 bit)
  +
Modulus:
  +
00:be:dc:02:4a:f5:32:38:b2:cf:10:4f:78:d0:de:
  +
d0:82:0e:52:2b:7f:ab:d9:ee:5c:a0:81:4a:8c:2d:
  +
ae:60:ac:27:6c:12:ef:a6:6f:6f:62:23:74:d0:c2:
  +
d5:b8:83:80:66:a1:50:ea:58:ea:18:b3:17:49:a6:
  +
6d:83:b9:d3:0b:a5:20:c1:5c:5a:54:d6:40:56:c1:
  +
c4:60:59:b9:0b:fd:de:0c:d4:0b:03:7a:93:cd:f0:
  +
1f:94:25:ee:11:07:86:74:f3:e8:31:e5:66:99:4e:
  +
03:a0:89:ca:3e:8b:65:73:39:d8:69:91:c0:13:ba:
  +
6e:35:2a:60:e7:d9:e6:5b:53:ee:bd:12:4a:ba:1a:
  +
d0:70:60:e2:65:dc:52:9d:f8:cc:0c:ec:ff:db:d5:
  +
e3:12:a7:a0:91:04:a2:40:01:f3:1c:e4:5a:93:74:
  +
37:16:3c:e1:bf:22:fe:0a:a1:dd:ee:cd:37:2b:6f:
  +
29:47:14:b5:1b:66:57:98:b5:7e:02:b5:4b:54:ee:
  +
b4:e9:93:fa:c9:ed:4e:28:cc:dc:ab:68:42:fd:f7:
  +
c0:ee:89:15:2e:46:76:64:f8:ac:be:86:1d:54:4a:
  +
4a:29:d5:2d:71:59:34:f8:f0:0b:e5:fc:1c:14:11:
  +
d8:08:8b:79:0a:a7:8f:6b:61:30:b3:69:9a:90:12:
  +
c3:29
  +
Exponent: 65537 (0x10001)
  +
X509v3 extensions:
  +
X509v3 Key Usage: critical
  +
Certificate Sign, CRL Sign
  +
X509v3 Basic Constraints: critical
  +
CA:TRUE
  +
X509v3 Subject Key Identifier:
  +
DB:3A:73:7A:03:25:2E:17:48:46:58:67:19:AD:86:2E:04:3D:EB:EC
  +
X509v3 Authority Key Identifier:
  +
keyid:DB:3A:73:7A:03:25:2E:17:48:46:58:67:19:AD:86:2E:04:3D:EB:EC
  +
  +
Signature Algorithm: sha256WithRSAEncryption
  +
71:6f:56:d4:6a:b8:24:9d:fc:16:47:8c:1c:59:ac:c2:92:90:
  +
36:5f:ef:73:43:c7:d7:2e:20:b4:4b:e9:3f:57:b4:a6:b4:82:
  +
a2:28:bd:f2:98:07:a1:49:df:c7:1d:60:5a:56:fc:85:64:e7:
  +
d8:97:75:f6:36:66:1a:04:ab:57:8a:43:d8:3c:aa:97:72:5e:
  +
3d:85:59:d9:d3:b6:2b:d5:aa:d6:49:ad:35:04:2c:22:52:9c:
  +
61:6a:6b:2f:dd:ba:78:cc:b7:ac:9c:fa:6d:1e:57:62:8f:b8:
  +
94:f9:98:30:d5:c1:06:24:c0:17:58:46:fd:6e:55:92:6f:98:
  +
11:d8:cd:28:6f:92:cb:90:5d:5e:91:b3:aa:bb:fd:d0:f5:32:
  +
9a:ed:a4:80:5a:7e:e6:6b:5d:98:19:71:04:86:de:18:e2:38:
  +
37:0f:e2:61:0a:d3:81:c0:06:1f:e7:f0:a0:c5:8f:f7:90:8f:
  +
c9:74:d5:68:1d:33:b4:a5:45:fc:f7:8c:35:a6:3a:1d:a7:6a:
  +
11:a5:1b:e1:7b:d8:2c:2a:87:5c:13:50:d1:c7:10:92:8c:ba:
  +
98:93:22:cd:81:b2:30:98:44:c5:54:c3:50:3a:30:16:39:91:
  +
2f:0a:ad:38:b3:44:c2:19:08:b2:a3:49:0a:15:63:81:7c:63:
  +
b9:4c:8e:7c
  +
</PRE>
  +
===URL для корневого CA===
  +
Публикуем URL’ы для корневого центра сертификации
  +
<PRE>
  +
vault write pki_root_ca/config/urls \
  +
issuing_certificates="http://vault.home:8200/v1/pki_root_ca/ca" \
  +
crl_distribution_points="http://vault.home:8200/v1/pki_root_ca/crl
  +
</PRE>
  +
  +
==Создание промежуточного СА==
  +
В целом можно использовать и корневой СА для создания конечных сертификатов но "лучшие собаководы" рекомендуют использовать промежуточный CA
  +
  +
===Конфигурация Vault===
  +
<PRE>
  +
vault secrets enable \
  +
-path=pki_intermediate_ca \
  +
-description="PKI Intermediate CA" \
  +
-max-lease-ttl="175200h" \
  +
pki
  +
</PRE>
  +
<PRE>
  +
Success! Enabled the pki secrets engine at: pki_intermediate_ca/
  +
</PRE>
  +
  +
  +
===Генерация запроса на сертификат для промежуточного CA===
  +
<PRE>
  +
vault write -format=json pki_intermediate_ca/intermediate/generate/internal \
  +
common_name="Intermediate CA" \
  +
country="Ukraine" \
  +
locality="Kharkov" \
  +
street_address="Lui Pastera st. 322 app. 131" \
  +
postal_code="101000" \
  +
organization="Horns and Hooves LLC" \
  +
ou="IT" \
  +
ttl="175200h" > pki_intermediate_ca.csr.json
  +
</PRE>
  +
====Просмотр результатов====
  +
=====Сырой вывод=====
  +
<PRE>
  +
{
  +
"request_id": "2e544789-ed06-1d6f-97cf-928c1fb54e77",
  +
"lease_id": "",
  +
"lease_duration": 0,
  +
"renewable": false,
  +
"data": {
  +
"csr": "-----BEGIN CERTIFICATE REQUEST-----\nMIIC6DCCAdACAQAwgaIxEDAOBgNVBAYTB1VrcmFpbmUxEDAOBgNVBAcTB0toYXJr\nb3YxJTAjBgNVBAkTHEx1aSBQYXN0ZXJhIHN0LiAzMjIgYXBwLiAxMzExDzANBgNV\nBBETBjEwMTAwMDEdMBsGA1UEChMUSG9ybnMgYW5kIEhvb3ZlcyBMTEMxCzAJBgNV\nBAsTAklUMRgwFgYDVQQDEw9JbnRlcm1lZGlhdGUgQ0EwggEiMA0GCSqGSIb3DQEB\nAQUAA4IBDwAwggEKAoIBAQDIJlmWRZBXLgMymWtlUCn9+3I1BS1W+Kyya2Tguc9R\nblhcyjzb1DshtkJAdohm3bwPnECCPyC3ARKOyN8xrepYOlphsn3+L3tpjOfvq7TS\nJXl194gjkURG7Ahz2FB/oPq0+d9YLYB/TTCh2H2r+3kXMX+ByJTcIHQ+03+6Er73\n+f0qOmYyy/U61lmjYGQTzlhLxzBWZ1xvLNJKaMGoZHgDyJ15bLyCcuSp0GYFnBht\nwvS3BL6wvuhon5NBTjLdnPRzYA8sbPq0SVppUQydaVY3vdBG3HsoWq2d9hQs6c56\nUyspaxpskKjpEdpSp///jfQ2cHAup4AeQBQaine+EfzFAgMBAAGgADANBgkqhkiG\n9w0BAQsFAAOCAQEAmhSXiyvK9J1ZarDQOx5XpPRZ+IfjvYhwcxJ5eBgVcJCljcpr\nAPSvc6dt9di9vHoT/YQ43t47bV0hxVxKERNfOHCjX9VuruOdJ5WE3ptRx0oQsMdC\nbuIxQv/j4F4+kZmLDiUfTsOVTGuOKVqPJ3nyMibeE0JhQHu58hprAosDc2kzFf31\n3KOrQHhpITVgGGPqM4VI/w7ghIzxL/qvPCMX3Qshe5lkHY1jTNt6zHeofC0QRIdo\n2P0Iteb0rR59+B1Bq+jBoKTFmyv1AKifeSY6syTpbp/rKyzeY8pe/txx3JOfF29K\nwMjCLShOPDmOmPPUCbq/vRTUl9zMBsC7tKYRbA==\n-----END CERTIFICATE REQUEST-----"
  +
},
  +
"warnings": null
  +
}
  +
</PRE>
  +
=====Сохранить запрос в файл=====
  +
<PRE>
  +
cat pki_intermediate_ca.csr.json | jq -r .data.csr
  +
</PRE>
  +
<PRE>
  +
-----BEGIN CERTIFICATE REQUEST-----
  +
MIIC6DCCAdACAQAwgaIxEDAOBgNVBAYTB1VrcmFpbmUxEDAOBgNVBAcTB0toYXJr
  +
b3YxJTAjBgNVBAkTHEx1aSBQYXN0ZXJhIHN0LiAzMjIgYXBwLiAxMzExDzANBgNV
  +
BBETBjEwMTAwMDEdMBsGA1UEChMUSG9ybnMgYW5kIEhvb3ZlcyBMTEMxCzAJBgNV
  +
BAsTAklUMRgwFgYDVQQDEw9JbnRlcm1lZGlhdGUgQ0EwggEiMA0GCSqGSIb3DQEB
  +
AQUAA4IBDwAwggEKAoIBAQDIJlmWRZBXLgMymWtlUCn9+3I1BS1W+Kyya2Tguc9R
  +
blhcyjzb1DshtkJAdohm3bwPnECCPyC3ARKOyN8xrepYOlphsn3+L3tpjOfvq7TS
  +
JXl194gjkURG7Ahz2FB/oPq0+d9YLYB/TTCh2H2r+3kXMX+ByJTcIHQ+03+6Er73
  +
+f0qOmYyy/U61lmjYGQTzlhLxzBWZ1xvLNJKaMGoZHgDyJ15bLyCcuSp0GYFnBht
  +
wvS3BL6wvuhon5NBTjLdnPRzYA8sbPq0SVppUQydaVY3vdBG3HsoWq2d9hQs6c56
  +
UyspaxpskKjpEdpSp///jfQ2cHAup4AeQBQaine+EfzFAgMBAAGgADANBgkqhkiG
  +
9w0BAQsFAAOCAQEAmhSXiyvK9J1ZarDQOx5XpPRZ+IfjvYhwcxJ5eBgVcJCljcpr
  +
APSvc6dt9di9vHoT/YQ43t47bV0hxVxKERNfOHCjX9VuruOdJ5WE3ptRx0oQsMdC
  +
buIxQv/j4F4+kZmLDiUfTsOVTGuOKVqPJ3nyMibeE0JhQHu58hprAosDc2kzFf31
  +
3KOrQHhpITVgGGPqM4VI/w7ghIzxL/qvPCMX3Qshe5lkHY1jTNt6zHeofC0QRIdo
  +
2P0Iteb0rR59+B1Bq+jBoKTFmyv1AKifeSY6syTpbp/rKyzeY8pe/txx3JOfF29K
  +
wMjCLShOPDmOmPPUCbq/vRTUl9zMBsC7tKYRbA==
  +
-----END CERTIFICATE REQUEST-----
  +
</PRE>
  +
<PRE>
  +
openssl req -in pki_intermediate_ca.csr -text -noout
  +
</PRE>
  +
<PRE>
  +
Certificate Request:
  +
Data:
  +
Version: 1 (0x0)
  +
Subject: C = Ukraine, L = Kharkov, street = Lui Pastera st. 322 app. 131, postalCode = 101000, O = Horns and Hooves LLC, OU = IT, CN = Intermediate CA
  +
Subject Public Key Info:
  +
Public Key Algorithm: rsaEncryption
  +
RSA Public-Key: (2048 bit)
  +
Modulus:
  +
00:c8:26:59:96:45:90:57:2e:03:32:99:6b:65:50:
  +
29:fd:fb:72:35:05:2d:56:f8:ac:b2:6b:64:e0:b9:
  +
cf:51:6e:58:5c:ca:3c:db:d4:3b:21:b6:42:40:76:
  +
88:66:dd:bc:0f:9c:40:82:3f:20:b7:01:12:8e:c8:
  +
df:31:ad:ea:58:3a:5a:61:b2:7d:fe:2f:7b:69:8c:
  +
e7:ef:ab:b4:d2:25:79:75:f7:88:23:91:44:46:ec:
  +
08:73:d8:50:7f:a0:fa:b4:f9:df:58:2d:80:7f:4d:
  +
30:a1:d8:7d:ab:fb:79:17:31:7f:81:c8:94:dc:20:
  +
74:3e:d3:7f:ba:12:be:f7:f9:fd:2a:3a:66:32:cb:
  +
f5:3a:d6:59:a3:60:64:13:ce:58:4b:c7:30:56:67:
  +
5c:6f:2c:d2:4a:68:c1:a8:64:78:03:c8:9d:79:6c:
  +
bc:82:72:e4:a9:d0:66:05:9c:18:6d:c2:f4:b7:04:
  +
be:b0:be:e8:68:9f:93:41:4e:32:dd:9c:f4:73:60:
  +
0f:2c:6c:fa:b4:49:5a:69:51:0c:9d:69:56:37:bd:
  +
d0:46:dc:7b:28:5a:ad:9d:f6:14:2c:e9:ce:7a:53:
  +
2b:29:6b:1a:6c:90:a8:e9:11:da:52:a7:ff:ff:8d:
  +
f4:36:70:70:2e:a7:80:1e:40:14:1a:8a:77:be:11:
  +
fc:c5
  +
Exponent: 65537 (0x10001)
  +
Attributes:
  +
a0:00
  +
Signature Algorithm: sha256WithRSAEncryption
  +
9a:14:97:8b:2b:ca:f4:9d:59:6a:b0:d0:3b:1e:57:a4:f4:59:
  +
f8:87:e3:bd:88:70:73:12:79:78:18:15:70:90:a5:8d:ca:6b:
  +
00:f4:af:73:a7:6d:f5:d8:bd:bc:7a:13:fd:84:38:de:de:3b:
  +
6d:5d:21:c5:5c:4a:11:13:5f:38:70:a3:5f:d5:6e:ae:e3:9d:
  +
27:95:84:de:9b:51:c7:4a:10:b0:c7:42:6e:e2:31:42:ff:e3:
  +
e0:5e:3e:91:99:8b:0e:25:1f:4e:c3:95:4c:6b:8e:29:5a:8f:
  +
27:79:f2:32:26:de:13:42:61:40:7b:b9:f2:1a:6b:02:8b:03:
  +
73:69:33:15:fd:f5:dc:a3:ab:40:78:69:21:35:60:18:63:ea:
  +
33:85:48:ff:0e:e0:84:8c:f1:2f:fa:af:3c:23:17:dd:0b:21:
  +
7b:99:64:1d:8d:63:4c:db:7a:cc:77:a8:7c:2d:10:44:87:68:
  +
d8:fd:08:b5:e6:f4:ad:1e:7d:f8:1d:41:ab:e8:c1:a0:a4:c5:
  +
9b:2b:f5:00:a8:9f:79:26:3a:b3:24:e9:6e:9f:eb:2b:2c:de:
  +
63:ca:5e:fe:dc:71:dc:93:9f:17:6f:4a:c0:c8:c2:2d:28:4e:
  +
3c:39:8e:98:f3:d4:09:ba:bf:bd:14:d4:97:dc:cc:06:c0:bb:
  +
b4:a6:11:6c
  +
</PRE>
  +
===Генерация сертификата по запросу===
  +
* <B>@pki_intermediate_ca.csr</B> - имя файла
  +
====Создание сертефиката====
  +
<PRE>
  +
vault write -format=json pki_root_ca/root/sign-intermediate csr=@pki_intermediate_ca.csr \
  +
country="Ukraine" \
  +
locality="Kharkov" \
  +
street_address="Lui Pastera st. 322 app. 131" \
  +
postal_code="61172" \
  +
organization="Home Network" \
  +
ou="IT" \
  +
format=pem_bundle \
  +
ttl="175200h" > intermediateCA.cert.pem.json
  +
</PRE>
  +
===="Сырой" результат====
  +
<PRE>
  +
{
  +
"request_id": "79f389eb-be78-dff6-e1b5-71034dc5fd87",
  +
"lease_id": "",
  +
"lease_duration": 0,
  +
"renewable": false,
  +
"data": {
  +
"certificate": "-----BEGIN CERTIFICATE-----\nMIIESTCCAzGgAwIBAgIUQLKqMu7qL4R1u4/sLphWcBxm9g0wDQYJKoZIhvcNAQEL\nBQAwgb0xEDAOBgNVBAYTB1VrcmFpbmUxEDAOBgNVBAcTB0toYXJrb3YxLTAPBgNV\nBAkTCGFwcC4gMTMxMBoGA1UECRMTTHVpIFBhc3RlcmEgU3QuIDMyMjEOMAwGA1UE\nERMFNjExNzIxFTATBgNVBAoTDEhvbWUgTmV0d29yazELMAkGA1UECxMCSVQxNDAy\nBgNVBAMTK1Jvb3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5IGZvciBIb21lIE5ldHdv\ncmswHhcNMjExMDExMDkyMjM3WhcNNDExMDA2MDkyMzA3WjCBmTEQMA4GA1UEBhMH\nVWtyYWluZTEQMA4GA1UEBxMHS2hhcmtvdjElMCMGA1UECRMcTHVpIFBhc3RlcmEg\nc3QuIDMyMiBhcHAuIDEzMTEOMAwGA1UEERMFNjExNzIxFTATBgNVBAoTDEhvbWUg\nTmV0d29yazELMAkGA1UECxMCSVQxGDAWBgNVBAMTD0ludGVybWVkaWF0ZSBDQTCC\nASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMgmWZZFkFcuAzKZa2VQKf37\ncjUFLVb4rLJrZOC5z1FuWFzKPNvUOyG2QkB2iGbdvA+cQII/ILcBEo7I3zGt6lg6\nWmGyff4ve2mM5++rtNIleXX3iCORREbsCHPYUH+g+rT531gtgH9NMKHYfav7eRcx\nf4HIlNwgdD7Tf7oSvvf5/So6ZjLL9TrWWaNgZBPOWEvHMFZnXG8s0kpowahkeAPI\nnXlsvIJy5KnQZgWcGG3C9LcEvrC+6Gifk0FOMt2c9HNgDyxs+rRJWmlRDJ1pVje9\n0EbceyharZ32FCzpznpTKylrGmyQqOkR2lKn//+N9DZwcC6ngB5AFBqKd74R/MUC\nAwEAAaNjMGEwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0O\nBBYEFFfMF8/PIZRxQrirBnz9/EVt+WpPMB8GA1UdIwQYMBaAFNs6c3oDJS4XSEZY\nZxmthi4EPevsMA0GCSqGSIb3DQEBCwUAA4IBAQCI5j1vsxGmb2zhd1p7rLJibntp\nJHxTg0qG9pDKzO3erUDia53ifTRchRjNqgcdTJO89MbCVpMcK88+E01X3KtGZMFR\n3V4I1Gmptdg4luicYzrO92S40CiRHr9UFz8Cftg9JxGZAk0MN3ScpjtxPM1fZs4d\n2INtQtyjtZ/I86itogPsKHo7hrIdo9IGmFa7OHuul/uYl3Z9cNLOAEHcBFarQ9Vn\nvQmPpdaq3t4ArwFHRrn5ZMgM9HbvRbgr3ns5U4uX9TdSefHashoAuVGvIFquMpVj\n0ajUAed1yuVd7S2USE1s8RyN7j3t0D7FG7pRECTBnZYKqBc7OI2YdiwdPvQH\n-----END CERTIFICATE-----",
  +
"expiration": 2264664187,
  +
"issuing_ca": "-----BEGIN CERTIFICATE-----\nMIIEbzCCA1egAwIBAgIUBVXFmyCRZoaWQoS9ZprBcCiNv4IwDQYJKoZIhvcNAQEL\nBQAwgb0xEDAOBgNVBAYTB1VrcmFpbmUxEDAOBgNVBAcTB0toYXJrb3YxLTAPBgNV\nBAkTCGFwcC4gMTMxMBoGA1UECRMTTHVpIFBhc3RlcmEgU3QuIDMyMjEOMAwGA1UE\nERMFNjExNzIxFTATBgNVBAoTDEhvbWUgTmV0d29yazELMAkGA1UECxMCSVQxNDAy\nBgNVBAMTK1Jvb3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5IGZvciBIb21lIE5ldHdv\ncmswIBcNMjExMDEwMTI1ODAwWhgPMjA1MTEwMDMxMjU4MjdaMIG9MRAwDgYDVQQG\nEwdVa3JhaW5lMRAwDgYDVQQHEwdLaGFya292MS0wDwYDVQQJEwhhcHAuIDEzMTAa\nBgNVBAkTE0x1aSBQYXN0ZXJhIFN0LiAzMjIxDjAMBgNVBBETBTYxMTcyMRUwEwYD\nVQQKEwxIb21lIE5ldHdvcmsxCzAJBgNVBAsTAklUMTQwMgYDVQQDEytSb290IENl\ncnRpZmljYXRlIEF1dGhvcml0eSBmb3IgSG9tZSBOZXR3b3JrMIIBIjANBgkqhkiG\n9w0BAQEFAAOCAQ8AMIIBCgKCAQEAvtwCSvUyOLLPEE940N7Qgg5SK3+r2e5coIFK\njC2uYKwnbBLvpm9vYiN00MLVuIOAZqFQ6ljqGLMXSaZtg7nTC6UgwVxaVNZAVsHE\nYFm5C/3eDNQLA3qTzfAflCXuEQeGdPPoMeVmmU4DoInKPotlcznYaZHAE7puNSpg\n59nmW1PuvRJKuhrQcGDiZdxSnfjMDOz/29XjEqegkQSiQAHzHORak3Q3FjzhvyL+\nCqHd7s03K28pRxS1G2ZXmLV+ArVLVO606ZP6ye1OKMzcq2hC/ffA7okVLkZ2ZPis\nvoYdVEpKKdUtcVk0+PAL5fwcFBHYCIt5CqePa2Ews2makBLDKQIDAQABo2MwYTAO\nBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQU2zpzegMl\nLhdIRlhnGa2GLgQ96+wwHwYDVR0jBBgwFoAU2zpzegMlLhdIRlhnGa2GLgQ96+ww\nDQYJKoZIhvcNAQELBQADggEBAHFvVtRquCSd/BZHjBxZrMKSkDZf73NDx9cuILRL\n6T9XtKa0gqIovfKYB6FJ38cdYFpW/IVk59iXdfY2ZhoEq1eKQ9g8qpdyXj2FWdnT\ntivVqtZJrTUELCJSnGFqay/dunjMt6yc+m0eV2KPuJT5mDDVwQYkwBdYRv1uVZJv\nmBHYzShvksuQXV6Rs6q7/dD1MprtpIBafuZrXZgZcQSG3hjiODcP4mEK04HABh/n\n8KDFj/eQj8l01WgdM7SlRfz3jDWmOh2nahGlG+F72Cwqh1wTUNHHEJKMupiTIs2B\nsjCYRMVUw1A6MBY5kS8KrTizRMIZCLKjSQoVY4F8Y7lMjnw=\n-----END CERTIFICATE-----",
  +
"serial_number": "40:b2:aa:32:ee:ea:2f:84:75:bb:8f:ec:2e:98:56:70:1c:66:f6:0d"
  +
},
  +
"warnings": null
  +
}
  +
</PRE>
  +
====PEM Файл====
  +
<PRE>
  +
cat intermediateCA.cert.pem.json | jq -r .data.certificate > intermediateCA.cert.pem
  +
</PRE>
  +
<PRE>
  +
-----BEGIN CERTIFICATE-----
  +
MIIESTCCAzGgAwIBAgIUQLKqMu7qL4R1u4/sLphWcBxm9g0wDQYJKoZIhvcNAQEL
  +
BQAwgb0xEDAOBgNVBAYTB1VrcmFpbmUxEDAOBgNVBAcTB0toYXJrb3YxLTAPBgNV
  +
BAkTCGFwcC4gMTMxMBoGA1UECRMTTHVpIFBhc3RlcmEgU3QuIDMyMjEOMAwGA1UE
  +
ERMFNjExNzIxFTATBgNVBAoTDEhvbWUgTmV0d29yazELMAkGA1UECxMCSVQxNDAy
  +
BgNVBAMTK1Jvb3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5IGZvciBIb21lIE5ldHdv
  +
cmswHhcNMjExMDExMDkyMjM3WhcNNDExMDA2MDkyMzA3WjCBmTEQMA4GA1UEBhMH
  +
VWtyYWluZTEQMA4GA1UEBxMHS2hhcmtvdjElMCMGA1UECRMcTHVpIFBhc3RlcmEg
  +
c3QuIDMyMiBhcHAuIDEzMTEOMAwGA1UEERMFNjExNzIxFTATBgNVBAoTDEhvbWUg
  +
TmV0d29yazELMAkGA1UECxMCSVQxGDAWBgNVBAMTD0ludGVybWVkaWF0ZSBDQTCC
  +
ASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMgmWZZFkFcuAzKZa2VQKf37
  +
cjUFLVb4rLJrZOC5z1FuWFzKPNvUOyG2QkB2iGbdvA+cQII/ILcBEo7I3zGt6lg6
  +
WmGyff4ve2mM5++rtNIleXX3iCORREbsCHPYUH+g+rT531gtgH9NMKHYfav7eRcx
  +
f4HIlNwgdD7Tf7oSvvf5/So6ZjLL9TrWWaNgZBPOWEvHMFZnXG8s0kpowahkeAPI
  +
nXlsvIJy5KnQZgWcGG3C9LcEvrC+6Gifk0FOMt2c9HNgDyxs+rRJWmlRDJ1pVje9
  +
0EbceyharZ32FCzpznpTKylrGmyQqOkR2lKn//+N9DZwcC6ngB5AFBqKd74R/MUC
  +
AwEAAaNjMGEwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0O
  +
BBYEFFfMF8/PIZRxQrirBnz9/EVt+WpPMB8GA1UdIwQYMBaAFNs6c3oDJS4XSEZY
  +
Zxmthi4EPevsMA0GCSqGSIb3DQEBCwUAA4IBAQCI5j1vsxGmb2zhd1p7rLJibntp
  +
JHxTg0qG9pDKzO3erUDia53ifTRchRjNqgcdTJO89MbCVpMcK88+E01X3KtGZMFR
  +
3V4I1Gmptdg4luicYzrO92S40CiRHr9UFz8Cftg9JxGZAk0MN3ScpjtxPM1fZs4d
  +
2INtQtyjtZ/I86itogPsKHo7hrIdo9IGmFa7OHuul/uYl3Z9cNLOAEHcBFarQ9Vn
  +
vQmPpdaq3t4ArwFHRrn5ZMgM9HbvRbgr3ns5U4uX9TdSefHashoAuVGvIFquMpVj
  +
0ajUAed1yuVd7S2USE1s8RyN7j3t0D7FG7pRECTBnZYKqBc7OI2YdiwdPvQH
  +
-----END CERTIFICATE-----
  +
</PRE>
  +
  +
====Детали сертефиката====
  +
<PRE>
  +
openssl x509 -in intermediateCA.cert.pem -noout -text
  +
Certificate:
  +
Data:
  +
Version: 3 (0x2)
  +
Serial Number:
  +
40:b2:aa:32:ee:ea:2f:84:75:bb:8f:ec:2e:98:56:70:1c:66:f6:0d
  +
Signature Algorithm: sha256WithRSAEncryption
  +
Issuer: C = Ukraine, L = Kharkov, street = app. 131 + street = Lui Pastera St. 322, postalCode = 61172, O = Home Network, OU = IT, CN = Root Certificate Authority for Home Network
  +
Validity
  +
Not Before: Oct 11 09:22:37 2021 GMT
  +
Not After : Oct 6 09:23:07 2041 GMT
  +
Subject: C = Ukraine, L = Kharkov, street = Lui Pastera st. 322 app. 131, postalCode = 61172, O = Home Network, OU = IT, CN = Intermediate CA
  +
Subject Public Key Info:
  +
Public Key Algorithm: rsaEncryption
  +
RSA Public-Key: (2048 bit)
  +
Modulus:
  +
00:c8:26:59:96:45:90:57:2e:03:32:99:6b:65:50:
  +
29:fd:fb:72:35:05:2d:56:f8:ac:b2:6b:64:e0:b9:
  +
cf:51:6e:58:5c:ca:3c:db:d4:3b:21:b6:42:40:76:
  +
88:66:dd:bc:0f:9c:40:82:3f:20:b7:01:12:8e:c8:
  +
df:31:ad:ea:58:3a:5a:61:b2:7d:fe:2f:7b:69:8c:
  +
e7:ef:ab:b4:d2:25:79:75:f7:88:23:91:44:46:ec:
  +
08:73:d8:50:7f:a0:fa:b4:f9:df:58:2d:80:7f:4d:
  +
30:a1:d8:7d:ab:fb:79:17:31:7f:81:c8:94:dc:20:
  +
74:3e:d3:7f:ba:12:be:f7:f9:fd:2a:3a:66:32:cb:
  +
f5:3a:d6:59:a3:60:64:13:ce:58:4b:c7:30:56:67:
  +
5c:6f:2c:d2:4a:68:c1:a8:64:78:03:c8:9d:79:6c:
  +
bc:82:72:e4:a9:d0:66:05:9c:18:6d:c2:f4:b7:04:
  +
be:b0:be:e8:68:9f:93:41:4e:32:dd:9c:f4:73:60:
  +
0f:2c:6c:fa:b4:49:5a:69:51:0c:9d:69:56:37:bd:
  +
d0:46:dc:7b:28:5a:ad:9d:f6:14:2c:e9:ce:7a:53:
  +
2b:29:6b:1a:6c:90:a8:e9:11:da:52:a7:ff:ff:8d:
  +
f4:36:70:70:2e:a7:80:1e:40:14:1a:8a:77:be:11:
  +
fc:c5
  +
Exponent: 65537 (0x10001)
  +
X509v3 extensions:
  +
X509v3 Key Usage: critical
  +
Certificate Sign, CRL Sign
  +
X509v3 Basic Constraints: critical
  +
CA:TRUE
  +
X509v3 Subject Key Identifier:
  +
57:CC:17:CF:CF:21:94:71:42:B8:AB:06:7C:FD:FC:45:6D:F9:6A:4F
  +
X509v3 Authority Key Identifier:
  +
keyid:DB:3A:73:7A:03:25:2E:17:48:46:58:67:19:AD:86:2E:04:3D:EB:EC
  +
  +
Signature Algorithm: sha256WithRSAEncryption
  +
88:e6:3d:6f:b3:11:a6:6f:6c:e1:77:5a:7b:ac:b2:62:6e:7b:
  +
69:24:7c:53:83:4a:86:f6:90:ca:cc:ed:de:ad:40:e2:6b:9d:
  +
e2:7d:34:5c:85:18:cd:aa:07:1d:4c:93:bc:f4:c6:c2:56:93:
  +
1c:2b:cf:3e:13:4d:57:dc:ab:46:64:c1:51:dd:5e:08:d4:69:
  +
a9:b5:d8:38:96:e8:9c:63:3a:ce:f7:64:b8:d0:28:91:1e:bf:
  +
54:17:3f:02:7e:d8:3d:27:11:99:02:4d:0c:37:74:9c:a6:3b:
  +
71:3c:cd:5f:66:ce:1d:d8:83:6d:42:dc:a3:b5:9f:c8:f3:a8:
  +
ad:a2:03:ec:28:7a:3b:86:b2:1d:a3:d2:06:98:56:bb:38:7b:
  +
ae:97:fb:98:97:76:7d:70:d2:ce:00:41:dc:04:56:ab:43:d5:
  +
67:bd:09:8f:a5:d6:aa:de:de:00:af:01:47:46:b9:f9:64:c8:
  +
0c:f4:76:ef:45:b8:2b:de:7b:39:53:8b:97:f5:37:52:79:f1:
  +
da:b2:1a:00:b9:51:af:20:5a:ae:32:95:63:d1:a8:d4:01:e7:
  +
75:ca:e5:5d:ed:2d:94:48:4d:6c:f1:1c:8d:ee:3d:ed:d0:3e:
  +
c5:1b:ba:51:10:24:c1:9d:96:0a:a8:17:3b:38:8d:98:76:2c:
  +
1d:3e:f4:07
  +
</PRE>
  +
  +
  +
====Валидация с помошью корневого CA====
  +
<PRE>
  +
openssl verify -verbose -CAfile rootCA.pem intermediateCA.cert.pem
  +
intermediateCA.cert.pem: OK
  +
</PRE>
  +
  +
  +
===Конфигурация Vault для использования промежуточного CA===
  +
====Загрузка промежуточного сертефиката====
  +
<PRE>
  +
vault write pki_intermediate_ca/intermediate/set-signed \
  +
certificate=@intermediateCA.cert.pem
  +
</PRE>
  +
  +
====Configure URLs====
  +
<PRE>
  +
vault write pki_intermediate_ca/config/urls \
  +
issuing_certificates="http://vault.home:8200/v1/pki_intermediate_ca/ca" \
  +
crl_distribution_points="http://vault.home:8200/v1/pki_intermediate_ca/crl"
  +
</PRE>
  +
  +
=Работа с PKI=
  +
Создание пользователей и ролей не относится непосредсвенно к настройке PKI но доьбавлено для полноты так как все равно надо настроить =)
  +
==Роли==
  +
По сути роли здесь - это <B>Путь</B> к которому нужно будет дать доступ с помошью политик
  +
===Тестовая роль для серверных сертификатов===
  +
  +
* <B>example-dot-home-server-server-crt</B> - имя роли
  +
<PRE>
  +
vault write pki_intermediate_ca/roles/example-dot-home-server-crt \
  +
country="Ukraine" \
  +
locality="Kharkov" \
  +
street_address="Lui Pastera st 322 app. 311"\
  +
postal_code="61172" \
  +
organization="Home Network" \
  +
ou="IT" \
  +
allowed_domains="example.home" \
  +
allow_subdomains=true \
  +
max_ttl="87600h" \
  +
key_bits="2048" \
  +
key_type="rsa" \
  +
allow_any_name=false \
  +
allow_bare_domains=false \
  +
allow_glob_domain=false \
  +
allow_ip_sans=true \
  +
allow_localhost=false \
  +
client_flag=false \
  +
server_flag=true \
  +
enforce_hostnames=true \
  +
key_usage="DigitalSignature,KeyEncipherment" \
  +
ext_key_usage="ServerAuth" \
  +
require_cn=true
  +
</PRE>
  +
  +
===Тестовая роль для клиентских сертификатов===
  +
<PRE>
  +
vault write pki_intermediate_ca/roles/example-dot-home-client-crt \
  +
country="Ukraine" \
  +
locality="Kharkov" \
  +
street_address="Lui Pastera st. 322 app. 131" \
  +
postal_code="61172" \
  +
organization="Home Network" \
  +
ou="IT" \
  +
allow_subdomains=true \
  +
max_ttl="87600h" \
  +
key_bits="2048" \
  +
key_type="rsa" \
  +
allow_any_name=true \
  +
allow_bare_domains=false \
  +
allow_glob_domain=false \
  +
allow_ip_sans=false \
  +
allow_localhost=false \
  +
client_flag=true \
  +
server_flag=false \
  +
enforce_hostnames=false \
  +
key_usage="DigitalSignature" \
  +
ext_key_usage="ClientAuth" \
  +
require_cn=true
  +
</PRE>
  +
  +
  +
===Просмотр ролей===
  +
<PRE>
  +
vault list pki_intermediate_ca/roles
  +
Keys
  +
----
  +
example-dot-home-client-crt
  +
example-dot-home-server-crt
  +
</PRE>
  +
  +
<PRE>
  +
vault read pki_intermediate_ca/roles/example-dot-home-server-crt
  +
Key Value
  +
--- -----
  +
allow_any_name false
  +
allow_bare_domains false
  +
allow_glob_domains false
  +
allow_ip_sans true
  +
allow_localhost false
  +
allow_subdomains true
  +
allow_token_displayname false
  +
allowed_domains [example.home]
  +
allowed_domains_template false
  +
allowed_other_sans []
  +
allowed_serial_numbers []
  +
allowed_uri_sans []
  +
basic_constraints_valid_for_non_ca false
  +
client_flag false
  +
code_signing_flag false
  +
country [Ukraine]
  +
email_protection_flag false
  +
enforce_hostnames true
  +
ext_key_usage [ServerAuth]
  +
ext_key_usage_oids []
  +
generate_lease false
  +
key_bits 2048
  +
key_type rsa
  +
key_usage [DigitalSignature KeyEncipherment]
  +
locality [Kharkov]
  +
max_ttl 87600h
  +
no_store false
  +
not_before_duration 30s
  +
organization [Home Network]
  +
ou [IT]
  +
policy_identifiers []
  +
postal_code [61172]
  +
province []
  +
require_cn true
  +
server_flag true
  +
street_address [Lui Pastera st 322 app. 311]
  +
ttl 0s
  +
use_csr_common_name true
  +
use_csr_sans true
  +
</PRE>
  +
  +
  +
==Политики==
  +
  +
* По сути политики определяют права доступа ТОКЕНА к определнному пути. Токен же выдается при логине - т е в простейшем случае политики должны назначаться на пользователя (авторизация по логину/паролю)
  +
  +
Для доступа к ролям создаем 2 файла с политиками:
  +
===Политика для серверных сертефикатов===
  +
<PRE>
  +
example-dot-home-server-crt-policy.hlc
  +
</PRE>
  +
<PRE>
  +
path "pki_intermediate_ca/issue/example-dot-home-server-crt"
  +
{
  +
capabilities = ["read", "create", "list", "update"]
  +
}
  +
</PRE>
  +
===Политика для клиентских сертефикатов===
  +
<PRE>
  +
example-dot-home-client-crt-policy.hlc
  +
</PRE>
  +
<PRE>
  +
path "pki_intermediate_ca/issue/example-dot-home-client-crt"
  +
{
  +
capabilities = ["read", "create", "list", "update"]
  +
}
  +
</PRE>
  +
  +
===Создание политик из файлов===
  +
<PRE>
  +
vault policy write example-dot-home-server-crt-policy example-dot-home-server-crt-policy.hlc
  +
</PRE>
  +
<PRE>
  +
vault policy write example-dot-home-client-crt-policy example-dot-home-client-crt-policy.hlc
  +
</PRE>
  +
  +
===Проверка созданных политик===
  +
<PRE>
  +
vault policy list
  +
default
  +
example-dot-home-client-crt-policy
  +
example-dot-home-server-crt-policy
  +
root
  +
</PRE>
  +
  +
<PRE>
  +
vault policy read example-dot-home-server-crt-policy
  +
path "pki_intermediate_ca/issue/example-dot-home-server-crt"
  +
{
  +
capabilities = ["read", "create", "list", "update"]
  +
}
  +
</PRE>
  +
<PRE>
  +
vault policy read example-dot-home-client-crt-policy
  +
path "pki_intermediate_ca/issue/example-dot-home-client-crt"
  +
{
  +
capabilities = ["read", "create", "list", "update"]
  +
}
  +
</PRE>
  +
  +
==Привязка политик к пользователям==
  +
* Пользователи с логином и паролем хорошо подходят для тестирования - в реальных окружениях будет использоваться что-то дроугое, сервисные аккаунты или еще что-то.
  +
* Включить авторизацию по логину/паролю нужно заранее (https://noname.com.ua/mediawiki/index.php/Vault)
  +
===Просмотр пользователей===
  +
<PRE>
  +
vault list auth/userpass/users
  +
</PRE>
  +
===Создание пользователей===
  +
* Политики перечисляются через запятую (что не очевидно)
  +
* Имена пользователей "говорят" о их назначении
  +
* Пароли простые для тестирования но разные у разных пользователей (для того что бы не допустить ошибок при тестировании и не перепутать пользователя)
  +
  +
===Пользователь для получения серверных сертификатов===
  +
<PRE>
  +
vault \
  +
write auth/userpass/users/example-dot-home-server-crt-user \
  +
password=server \
  +
policies="example-dot-home-server-crt-policy,default"
  +
</PRE>
  +
  +
===Пользователь для получения клиентских сертификатов===
  +
<PRE>
  +
vault \
  +
write auth/userpass/users/example-dot-home-client-crt-user \
  +
password=client \
  +
policies="example-dot-home-client-crt-policy,default"
  +
</PRE>
  +
===Пользователь для получения и серверных и клиентских сертификатов===
  +
<PRE>
  +
vault \
  +
write auth/userpass/users/example-dot-home-any-crt-user \
  +
password=any \
  +
policies="example-dot-home-server-crt-policy,example-dot-home-client-crt-policy,default"
  +
</PRE>
  +
  +
===Просмотр созданных пользователей===
  +
<PRE>
  +
vault list auth/userpass/users
  +
Keys
  +
----
  +
example-dot-home-any-crt-user
  +
example-dot-home-client-crt-user
  +
example-dot-home-server-crt-user
  +
</PRE>
  +
  +
<PRE>
  +
vault read auth/userpass/users/example-dot-home-any-crt-user
  +
Key Value
  +
--- -----
  +
policies [default example-dot-home-client-crt-policy example-dot-home-server-crt-policy]
  +
token_bound_cidrs []
  +
token_explicit_max_ttl 0s
  +
token_max_ttl 0s
  +
token_no_default_policy false
  +
token_num_uses 0
  +
token_period 0s
  +
token_policies [default example-dot-home-client-crt-policy example-dot-home-server-crt-policy]
  +
token_ttl 0s
  +
token_type default
  +
</PRE>
  +
<PRE>
  +
vault read auth/userpass/users/example-dot-home-server-crt-user
  +
</PRE>
  +
<PRE>
  +
Key Value
  +
--- -----
  +
policies [default example-dot-home-server-crt-policy]
  +
token_bound_cidrs []
  +
token_explicit_max_ttl 0s
  +
token_max_ttl 0s
  +
token_no_default_policy false
  +
token_num_uses 0
  +
token_period 0s
  +
token_policies [default example-dot-home-server-crt-policy]
  +
token_ttl 0s
  +
token_type default
  +
</PRE>
  +
<PRE>
  +
vault read auth/userpass/users/example-dot-home-client-crt-user
  +
</PRE>
  +
<PRE>
  +
Key Value
  +
--- -----
  +
policies [default example-dot-home-client-crt-policy]
  +
token_bound_cidrs []
  +
token_explicit_max_ttl 0s
  +
token_max_ttl 0s
  +
token_no_default_policy false
  +
token_num_uses 0
  +
token_period 0s
  +
token_policies [default example-dot-home-client-crt-policy]
  +
token_ttl 0s
  +
token_type default
  +
</PRE>
  +
  +
==Проверка получения сертефикатов==
  +
===Получение серверного сертефиката===
  +
====Авторизация с логином и паролем====
  +
<PRE>
  +
vault \
  +
login \
  +
-method=userpass \
  +
username=example-dot-home-server-crt-user \
  +
password=server
  +
</PRE>
  +
<PRE>
  +
Key Value
  +
--- -----
  +
token s.Wiy7YVCrte88i0QIHc4jmvQP
  +
token_accessor ptB7o9d6yOq5w4Ra5Q44W1FF
  +
token_duration 768h
  +
token_renewable true
  +
token_policies ["default" "example-dot-home-server-crt-policy"]
  +
identity_policies []
  +
policies ["default" "example-dot-home-server-crt-policy"]
  +
token_meta_username example-dot-home-server-crt-user
  +
</PRE>
  +
====Получение сертефиката====
  +
<PRE>
  +
vault write -format=json pki_intermediate_ca/issue/example-dot-home-server-crt \
  +
common_name="vault.example.home" \
  +
alt_names="pki.example.home" \
  +
ttl="43800h" > vault.example.home.crt
  +
</PRE>
  +
  +
  +
====Проверка полученного сертефиката====
  +
<PRE>
  +
cat vault.example.home.crt
  +
{
  +
"request_id": "3d679cb8-0aa1-9920-672e-b56831fc53b8",
  +
"lease_id": "",
  +
"lease_duration": 0,
  +
"renewable": false,
  +
"data": {
  +
"ca_chain": [
  +
"-----BEGIN CERTIFICATE-----uVGvIFquMpVj\n0ajUAed1yuVd7S2USE1s8RyN7j3t0D7FG7pRECTBnZYKqBc7OI2YdiwdPvQH\n-----END CERTIFICATE-----"
  +
],
  +
"certificate": "-----BEGIN CERTIFICATE-----dNVFGyG16ZABF66E1j1O/MTRjB3cZIHj1rMP\nc84dH3ykPoe80T6zGblRgxrZOIh/EQ==\n-----END CERTIFICATE-----",
  +
"expiration": 1791633878,
  +
"issuing_ca": "-----BEGIN CERTIFICATE-----uVGvIFquMpVj\n0ajUAed1yuVd7S2USE1s8RyN7j3t0D7FG7pRECTBnZYKqBc7OI2YdiwdPvQH\n-----END CERTIFICATE-----",
  +
"private_key": "-----BEGIN RSA PRIVATE KEY-----aAg7YWcEsZMl\ntdqBAoGAX5UJPX9VSbm/kI5nruAnQXcfkmUWIQA3GDWdbGfqaY4AZZleQv/0mMJf\nAgUT+e/vFuHaDAxY6rXh7dl3aM3JiJgdLxJ1vFFeaKqHHonH83PT0921S+MLiB5/\n9EdomgHndqzJXVrMLThUR6PiUTZtrG48tsI6w9rOk1ZELvE5HJI=\n-----END RSA PRIVATE KEY-----",
  +
"private_key_type": "rsa",
  +
"serial_number": "3b:a5:4d:03:64:bf:91:b5:6a:6f:0a:c8:aa:05:11:68:29:a8:6d:dd"
  +
},
  +
"warnings": null
  +
}
  +
</PRE>
  +
<PRE>
  +
cat vault.example.home.crt | jq -r .data.ca_chain[] > ca_chain.pem
  +
cat vault.example.home.crt | jq -r .data.certificate > certificate.pem
  +
cat vault.example.home.crt | jq -r .data.issuing_ca > issuing_ca.pem
  +
</PRE>
  +
  +
=====Сертификат сервера=====
  +
Наиболее интересные поля - ожидаемые значения:
  +
  +
* CN = vault.example.home
  +
* X509v3 Subject Alternative Name: DNS:pki.example.home, DNS:vault.example.home
  +
  +
<PRE>
  +
openssl x509 -in certificate.pem -text -noout
  +
</PRE>
  +
<PRE>
  +
Certificate:
  +
Data:
  +
Version: 3 (0x2)
  +
Serial Number:
  +
3b:a5:4d:03:64:bf:91:b5:6a:6f:0a:c8:aa:05:11:68:29:a8:6d:dd
  +
Signature Algorithm: sha256WithRSAEncryption
  +
Issuer: C = Ukraine, L = Kharkov, street = Lui Pastera st. 322 app. 131, postalCode = 61172, O = Home Network, OU = IT, CN = Intermediate CA
  +
Validity
  +
Not Before: Oct 11 12:04:12 2021 GMT
  +
Not After : Oct 10 12:04:38 2026 GMT
  +
Subject: C = Ukraine, L = Kharkov, street = Lui Pastera st 322 app. 311, postalCode = 61172, O = Home Network, OU = IT, CN = vault.example.home
  +
Subject Public Key Info:
  +
Public Key Algorithm: rsaEncryption
  +
RSA Public-Key: (2048 bit)
  +
Modulus:
  +
Exponent: 65537 (0x10001)
  +
X509v3 extensions:
  +
X509v3 Key Usage: critical
  +
Digital Signature, Key Encipherment
  +
X509v3 Extended Key Usage:
  +
TLS Web Server Authentication
  +
X509v3 Subject Key Identifier:
  +
5B:00:DB:44:EB:59:B4:9A:86:BE:9D:3D:A3:E0:DC:C6:EC:71:E4:BB
  +
X509v3 Authority Key Identifier:
  +
keyid:57:CC:17:CF:CF:21:94:71:42:B8:AB:06:7C:FD:FC:45:6D:F9:6A:4F
  +
  +
Authority Information Access:
  +
CA Issuers - URI:http://vault.home:8200/v1/pki_intermediate_ca/ca
  +
  +
X509v3 Subject Alternative Name:
  +
DNS:pki.example.home, DNS:vault.example.home
  +
X509v3 CRL Distribution Points:
  +
  +
Full Name:
  +
URI:http://vault.home:8200/v1/pki_intermediate_ca/crl
  +
  +
Signature Algorithm: sha256WithRSAEncryption
  +
</PRE>
  +
=====Промежуточный CA=====
  +
<PRE>
  +
openssl x509 -in issuing_ca.pem -text -noout
  +
Certificate:
  +
Data:
  +
Version: 3 (0x2)
  +
Serial Number:
  +
40:b2:aa:32:ee:ea:2f:84:75:bb:8f:ec:2e:98:56:70:1c:66:f6:0d
  +
Signature Algorithm: sha256WithRSAEncryption
  +
Issuer: C = Ukraine, L = Kharkov, street = app. 131 + street = Lui Pastera St. 322, postalCode = 61172, O = Home Network, OU = IT, CN = Root Certificate Authority for Home Network
  +
Validity
  +
Not Before: Oct 11 09:22:37 2021 GMT
  +
Not After : Oct 6 09:23:07 2041 GMT
  +
Subject: C = Ukraine, L = Kharkov, street = Lui Pastera st. 322 app. 131, postalCode = 61172, O = Home Network, OU = IT, CN = Intermediate CA
  +
Subject Public Key Info:
  +
Public Key Algorithm: rsaEncryption
  +
RSA Public-Key: (2048 bit)
  +
Modulus:
  +
Exponent: 65537 (0x10001)
  +
X509v3 extensions:
  +
X509v3 Key Usage: critical
  +
Certificate Sign, CRL Sign
  +
X509v3 Basic Constraints: critical
  +
CA:TRUE
  +
X509v3 Subject Key Identifier:
  +
57:CC:17:CF:CF:21:94:71:42:B8:AB:06:7C:FD:FC:45:6D:F9:6A:4F
  +
X509v3 Authority Key Identifier:
  +
keyid:DB:3A:73:7A:03:25:2E:17:48:46:58:67:19:AD:86:2E:04:3D:EB:EC
  +
  +
Signature Algorithm: sha256WithRSAEncryption
  +
</PRE>
  +
  +
=====Верефикация=====
  +
* Указать промежуточный как untrusted (или добавить rootCA в доверенные)
  +
<PRE>
  +
openssl verify -verbose -CAfile rootCA.pem -untrusted issuing_ca.pem certificate.pem
  +
certificate.pem: OK
  +
</PRE>
  +
  +
===Получение клиентского сертефиката===
  +
====Проверка прав====
  +
С "серверным" пользователем - нет прав
  +
<PRE>
  +
URL: PUT http://vault.home:8200/v1/pki_intermediate_ca/issue/example-dot-home-client-crt
  +
Code: 403. Errors:
  +
  +
* 1 error occurred:
  +
* permission denied
  +
</PRE>
  +
====Получение клиентского сертификата c правильным пользователем====
  +
<PRE>
  +
vault \
  +
login \
  +
-method=userpass \
  +
username=example-dot-home-client-crt-user \
  +
password=client
  +
  +
vault write -format=json pki_intermediate_ca/issue/example-dot-home-client-crt \
  +
common_name="vault.example.home" \
  +
alt_names="pki.example.home" \
  +
ttl="43800h" > vault.example.home.CLIENT.json
  +
</PRE>
  +
Ожидаемый результат:
  +
<PRE>
  +
X509v3 Extended Key Usage:
  +
TLS Web Client Authentication
  +
</PRE>
  +
<PRE>
  +
openssl x509 -noout -text -in certificate_client.pem
  +
Certificate:
  +
Data:
  +
Version: 3 (0x2)
  +
Serial Number:
  +
29:02:a3:28:8e:fc:48:bd:1a:5b:f9:46:e1:bf:87:27:e0:80:79:c3
  +
Signature Algorithm: sha256WithRSAEncryption
  +
Issuer: C = Ukraine, L = Kharkov, street = Lui Pastera st. 322 app. 131, postalCode = 61172, O = Home Network, OU = IT, CN = Intermediate CA
  +
Validity
  +
Not Before: Oct 11 12:31:10 2021 GMT
  +
Not After : Oct 10 12:31:37 2026 GMT
  +
Subject: C = Ukraine, L = Kharkov, street = Lui Pastera st. 322 app. 131, postalCode = 61172, O = Home Network, OU = IT, CN = vault.example.home
  +
Subject Public Key Info:
  +
Public Key Algorithm: rsaEncryption
  +
RSA Public-Key: (2048 bit)
  +
Modulus:
  +
Exponent: 65537 (0x10001)
  +
X509v3 extensions:
  +
X509v3 Key Usage: critical
  +
Digital Signature
  +
X509v3 Extended Key Usage:
  +
TLS Web Client Authentication
  +
X509v3 Subject Key Identifier:
  +
4A:1E:33:0C:03:E0:91:6D:17:1E:2B:4A:9F:53:98:7D:4C:80:43:83
  +
</PRE>
  +
  +
===Проверка прав для пользователя any===
  +
* работает каки ожидалось - можно получить сертификаты как для сервера так и для клиента
  +
<PRE>
  +
vault \
  +
login \
  +
-method=userpass \
  +
username=example-dot-home-any-crt-user \
  +
password=any
  +
  +
  +
vault write -format=json pki_intermediate_ca/issue/example-dot-home-client-crt \
  +
common_name="vault.example.home" \
  +
alt_names="pki.example.home" \
  +
ttl="43800h" > vault.example.home.CLIENT_by_any_user.json
  +
  +
  +
vault write -format=json pki_intermediate_ca/issue/example-dot-home-server-crt \
  +
common_name="vault.example.home" \
  +
alt_names="pki.example.home" \
  +
ttl="43800h" > vault.example.home.SERVER_by_any_user.json
  +
</PRE>
  +
  +
=Работа с PKI=
  +
==Посмотреть список сертификатов==
  +
<PRE>
  +
vault list pki_intermediate_ca/certs
  +
Keys
  +
----
  +
0e-be-9c-c3-80-0c-e2-51-e0-f8-e3-00-0d-5a-42-d3-cd-13-54-be
  +
10-3c-b0-8c-50-8c-4f-21-14-a6-fd-32-36-87-ce-85-ef-e9-23-d2
  +
29-02-a3-28-8e-fc-48-bd-1a-5b-f9-46-e1-bf-87-27-e0-80-79-c3
  +
29-6a-69-20-c3-c2-a8-f3-ae-e7-13-0c-6b-52-c5-b6-49-c4-a3-77
  +
38-b4-31-fc-82-6a-39-26-08-29-24-2d-da-ed-63-95-5c-7d-77-2b
  +
3b-a5-4d-03-64-bf-91-b5-6a-6f-0a-c8-aa-05-11-68-29-a8-6d-dd
  +
40-b2-aa-32-ee-ea-2f-84-75-bb-8f-ec-2e-98-56-70-1c-66-f6-0d
  +
</PRE>
  +
==Прочитать сертификат==
  +
* <B>40-b2-aa-32-ee-ea-2f-84-75-bb-8f-ec-2e-98-56-70-1c-66-f6-0d</B> это serial сертификата
  +
<PRE>
  +
vault read pki_intermediate_ca/cert/40-b2-aa-32-ee-ea-2f-84-75-bb-8f-ec-2e-98-56-70-1c-66-f6-0d --format=json
  +
</PRE>
  +
<PRE>
  +
{
  +
"request_id": "a7af8390-c94b-6055-2148-283746cd64fa",
  +
"lease_id": "",
  +
"lease_duration": 0,
  +
"renewable": false,
  +
"data": {
  +
"certificate": "-----BEGIN CERTIFICATE-----\nMIIESTCCAzGgAwIBAgIUQLKqMu7qL4R1u4/sLphWcBxm9g0wDQYJKoZIhvcNAQEL\nBQAwgb0xEDAOBgNVBAYTB1VrcmFpbmUxEDAOBgNVBAcTB0toYXJrb3YxLTAPBgNV\nBAkTCGFwcC4gMTMxMBoGA1UECRMTTHVpIFBhc3RlcmEgU3QuIDMyMjEOMAwGA1UE\nERMFNjExNzIxFTATBgNVBAoTDEhvbWUgTmV0d29yazELMAkGA1UECxMCSVQxNDAy\nBgNVBAMTK1Jvb3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5IGZvciBIb21lIE5ldHdv\ncmswHhcNMjExMDExMDkyMjM3WhcNNDExMDA2MDkyMzA3WjCBmTEQMA4GA1UEBhMH\nVWtyYWluZTEQMA4GA1UEBxMHS2hhcmtvdjElMCMGA1UECRMcTHVpIFBhc3RlcmEg\nc3QuIDMyMiBhcHAuIDEzMTEOMAwGA1UEERMFNjExNzIxFTATBgNVBAoTDEhvbWUg\nTmV0d29yazELMAkGA1UECxMCSVQxGDAWBgNVBAMTD0ludGVybWVkaWF0ZSBDQTCC\nASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMgmWZZFkFcuAzKZa2VQKf37\ncjUFLVb4rLJrZOC5z1FuWFzKPNvUOyG2QkB2iGbdvA+cQII/ILcBEo7I3zGt6lg6\nWmGyff4ve2mM5++rtNIleXX3iCORREbsCHPYUH+g+rT531gtgH9NMKHYfav7eRcx\nf4HIlNwgdD7Tf7oSvvf5/So6ZjLL9TrWWaNgZBPOWEvHMFZnXG8s0kpowahkeAPI\nnXlsvIJy5KnQZgWcGG3C9LcEvrC+6Gifk0FOMt2c9HNgDyxs+rRJWmlRDJ1pVje9\n0EbceyharZ32FCzpznpTKylrGmyQqOkR2lKn//+N9DZwcC6ngB5AFBqKd74R/MUC\nAwEAAaNjMGEwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0O\nBBYEFFfMF8/PIZRxQrirBnz9/EVt+WpPMB8GA1UdIwQYMBaAFNs6c3oDJS4XSEZY\nZxmthi4EPevsMA0GCSqGSIb3DQEBCwUAA4IBAQCI5j1vsxGmb2zhd1p7rLJibntp\nJHxTg0qG9pDKzO3erUDia53ifTRchRjNqgcdTJO89MbCVpMcK88+E01X3KtGZMFR\n3V4I1Gmptdg4luicYzrO92S40CiRHr9UFz8Cftg9JxGZAk0MN3ScpjtxPM1fZs4d\n2INtQtyjtZ/I86itogPsKHo7hrIdo9IGmFa7OHuul/uYl3Z9cNLOAEHcBFarQ9Vn\nvQmPpdaq3t4ArwFHRrn5ZMgM9HbvRbgr3ns5U4uX9TdSefHashoAuVGvIFquMpVj\n0ajUAed1yuVd7S2USE1s8RyN7j3t0D7FG7pRECTBnZYKqBc7OI2YdiwdPvQH\n-----END CERTIFICATE-----",
  +
"revocation_time": 0
  +
},
  +
"warnings": null
  +
}
  +
</PRE>
  +
  +
==Отозвать сертификат==
  +
<PRE>
  +
vault write pki_intermediate_ca/revoke serial_number=
  +
<serial number>
  +
</PRE>
  +
==Очистить просроченные / отозванные сертификаты==
  +
<PRE>
  +
vault write pki_intermediate_ca/tidy \
  +
safety_buffer=5s \
  +
tidy_cert_store=true \
  +
tidy_revocation_list=true
  +
</PRE>
  +
=Проверка сертификатов с Nginx=
  +
Для проверки работы сертификатов настроим nginx как proxy. в качестве бекенда выступает сам Vault
  +
==Настройка Nginx==
  +
Предварительный конфиг виртуалхоста (пока не загружаю - так как ни ключа ни сертификата пока нет)
  +
<PRE>
  +
server {
  +
listen 8202 default_server ssl;
  +
root /var/www/html;
  +
server_name vault.home vault.local;
  +
access_log /var/log/nginx/vault-access.log postdata;
  +
error_log /var/log/nginx/vault-error.log;
  +
  +
ssl_certificate /etc/nginx/certs/vault.crt;
  +
ssl_certificate_key /etc/nginx/certs/vault.key;
  +
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
  +
ssl_ciphers HIGH:!aNULL:!MD5;
  +
  +
location / {
  +
client_body_buffer_size 64k;
  +
client_body_in_single_buffer on;
  +
proxy_pass http://127.0.0.1:8200;
  +
proxy_set_header Host $host:$server_port;
  +
proxy_set_header X-Real-IP $remote_addr;
  +
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
  +
proxy_set_header X-Forwarded-Proto $scheme;
  +
proxy_http_version 1.1;
  +
proxy_request_buffering off;
  +
}
  +
}
  +
</PRE>
  +
==Настройка Vault==
  +
===Создание роли===
  +
Роль ждя сертификата для домена vault.home
  +
<PRE>
  +
vault write pki_intermediate_ca/roles/vault-dot-home-server-crt \
  +
country="Ukraine" \
  +
locality="Kharkov" \
  +
street_address="Lui Pastera st 322 app. 311"\
  +
postal_code="61172" \
  +
organization="Home Network" \
  +
ou="IT" \
  +
allowed_domains="vault.home" \
  +
allow_subdomains=false \
  +
max_ttl="87600h" \
  +
key_bits="2048" \
  +
key_type="rsa" \
  +
allow_any_name=false \
  +
allow_bare_domains=true \
  +
allow_glob_domain=false \
  +
allow_ip_sans=true \
  +
allow_localhost=false \
  +
client_flag=false \
  +
server_flag=true \
  +
enforce_hostnames=true \
  +
key_usage="DigitalSignature,KeyEncipherment" \
  +
ext_key_usage="ServerAuth" \
  +
require_cn=true
  +
</PRE>
  +
  +
===Создание политик===
  +
* Файл vault-dot-home-server-crt-policy.hlc
  +
<PRE>
  +
path "pki_intermediate_ca/issue/vault-dot-home-server-crt"
  +
{
  +
capabilities = ["read", "create", "list", "update"]
  +
}
  +
</PRE>
  +
<PRE>
  +
vault \
  +
policy \
  +
write \
  +
vault-dot-home-server-crt-policy \
  +
vault-dot-home-server-crt-policy.hlc
  +
</PRE>
  +
===Создание пользователя для работы с сертефикатами===
  +
Еще раз подчеркну что пользователи используются тут ТОЛЬКО В ТЕСТОВЫХ ЦЕЛЯХ.
  +
====Существующие пользователи====
  +
<PRE>
  +
vault list auth/userpass/users
  +
Keys
  +
----
  +
example-dot-home-any-crt-user
  +
example-dot-home-client-crt-user
  +
example-dot-home-server-crt-user
  +
</PRE>
  +
====Новый пользователь с политикой для домена vault.home====
  +
  +
* username: vault-dot-home-server-crt-user
  +
* password: vault
  +
* политики: vault-dot-home-server-crt-policy и default
  +
  +
<PRE>
  +
vault \
  +
write auth/userpass/users/vault-dot-home-server-crt-user \
  +
password=vault \
  +
policies="vault-dot-home-server-crt-policy,default"
  +
</PRE>
  +
====Проверка====
  +
<PRE>
  +
export VAULT_ADDR="http://vault.home:8200"
  +
unset VAULT_TOKEN
  +
  +
  +
vault \
  +
login \
  +
-method=userpass \
  +
username=vault-dot-home-server-crt-user \
  +
password=vault
  +
  +
  +
vault \
  +
write \
  +
-format=json pki_intermediate_ca/issue/vault-dot-home-server-crt \
  +
common_name="vault.home" \
  +
ttl="43800h" > vault.home.crt
  +
</PRE>
  +
  +
==Подготовка Consul Template==
  +
===Установка===
  +
Так или иначе в зависимости от системы (это пример из интернета). Для arm версия другая.
  +
<PRE>
  +
$ wget https://releases.hashicorp.com/consul-template/0.19.5/consul-template_0.19.5_linux_amd64.zip
  +
$ apt-get install unzip
  +
$ unzip consul-template_0.19.5_linux_amd64.zip
  +
$ mv consul-template /user/local/bin
  +
</PRE>
  +
  +
===Темплейты для сертефиката и ключа===
  +
* /etc/consul-template.d/templates/vault-cert.tpl
  +
<PRE>
  +
{{- /* vault-cert.tpl */ -}}
  +
{{ with secret "pki_intermediate_ca/issue/vault-dot-home-server-crt" "common_name=vault.home" "ttl=2m" }}
  +
{{ .Data.certificate }}
  +
{{ .Data.issuing_ca }}{{ end }}
  +
</PRE>
  +
  +
  +
  +
* /etc/consul-template.d/templates/vault-key.tpl
  +
<PRE>
  +
{{- /* vault-dot-home-key.tpl */ -}}
  +
{{ with secret "pki_intermediate_ca/issue/vault-dot-home-server-crt" "common_name=vault.home" "ttl=2m"}}
  +
{{ .Data.private_key }}{{ end }}
  +
</PRE>
  +
  +
===Конфигурация consul-template===
  +
* /etc/consul-template.d/configs/nginx-vault.hcl
  +
  +
token пропущен так как авторизация через логин/пароль и токен получается динамически
  +
<PRE>
  +
vault {
  +
address = "http://vault.home:8200"
  +
# token = "<TOKEN_HERE>"
  +
renew_token = true
  +
  +
retry {
  +
enabled = true
  +
attempts = 5
  +
backoff = "250ms"
  +
}
  +
}
  +
  +
template {
  +
source = "/etc/consul-template.d/templates/vault-cert.tpl"
  +
destination = "/etc/nginx/certs/vault.crt"
  +
perms = "0600"
  +
command = "systemctl reload nginx"
  +
}
  +
  +
template {
  +
source = "/etc/consul-template.d/templates/vault-key.tpl"
  +
destination = "/etc/nginx/certs/vault.key"
  +
perms = "0600"
  +
command = "systemctl reload nginx"
  +
}
  +
</PRE>
  +
  +
==Тестовый запуск==
  +
  +
Скрипт
  +
<PRE>
  +
#!/bin/bash
  +
  +
VAULT_TOKEN=$(vault \
  +
login \
  +
-method=userpass \
  +
username=vault-dot-home-server-crt-user \
  +
password=vault \
  +
--format=json | jq -r .auth.client_token
  +
)
  +
  +
  +
#echo ${VAULT_TOKEN}
  +
  +
export VAULT_TOKEN=${VAULT_TOKEN}
  +
  +
/usr/local/consul/bin/consul-template \
  +
-config /etc/consul-template.d/configs/nginx-vault.hcl
  +
</PRE>
  +
  +
==systemd unit==
  +
  +
Создаю Unit-file:
  +
* имя файла /etc/systemd/system/consul-template-vault-nginx.service
  +
* Юнит "с дебагом"
  +
* Кроме всего прочего выводит переменные окружения (что бы убедиться что они нормально загружаются) и переменные systemd
  +
* Токен сохраняется во временном файле и потом отттуда попадает в переменные окружения
  +
<PRE>
  +
[Unit]
  +
Description=consul-template for Nginx/Vault
  +
Requires=network-online.target
  +
After=network-online.target
  +
  +
[Service]
  +
EnvironmentFile=-/etc/default/consul-template
  +
EnvironmentFile=-/etc/default/%N
  +
EnvironmentFile=-/tmp/vault-token-%N
  +
  +
Restart=on-failure
  +
ExecStartPre=/usr/bin/env
  +
ExecStartPre=/bin/bash -c " echo b=%b"
  +
ExecStartPre=/bin/bash -c " echo g=%g"
  +
ExecStartPre=/bin/bash -c " echo G=%G"
  +
ExecStartPre=/bin/bash -c " echo H=%H"
  +
ExecStartPre=/bin/bash -c " echo i=%i"
  +
ExecStartPre=/bin/bash -c " echo j=%j"
  +
ExecStartPre=/bin/bash -c " echo m=%m"
  +
ExecStartPre=/bin/bash -c " echo n=%n"
  +
ExecStartPre=/bin/bash -c " echo N=%N"
  +
ExecStartPre=/bin/bash -c " echo p=%p"
  +
ExecStartPre=/bin/bash -c " echo u=%u"
  +
ExecStartPre=/bin/bash -c " echo U=%U"
  +
ExecStartPre=/bin/bash -c " echo v=%v"
  +
ExecStartPre=/bin/bash -c " echo %%"
  +
  +
ExecStartPre=/bin/bash -c "printf 'VAULT_TOKEN=' > /tmp/vault-token-%N; \
  +
/usr/local/vault/bin/vault \
  +
login \
  +
-method=userpass \
  +
username=$VAULT_USERNAME \
  +
password=$VAULT_PASSWORD \
  +
--format=json | jq -r .auth.client_token >> /tmp/vault-token-%N"
  +
  +
ExecStartPre=/usr/bin/env
  +
ExecStart=/usr/local/consul/bin/consul-template \
  +
$OPTIONS \
  +
-config='/etc/consul-template.d/configs/nginx-vault.hcl'
  +
  +
KillSignal=SIGINT
  +
  +
[Install]
  +
WantedBy=multi-user.target
  +
</PRE>
  +
==Проверка работы==
  +
Безопастность игнорируется в тестом окружении - в проде нужно спрятать токены
  +
<PRE>
  +
systemctl status consul-template-vault-nginx.service
  +
● consul-template-vault-nginx.service - consul-template for Nginx/Vault
  +
Loaded: loaded (/etc/systemd/system/consul-template-vault-nginx.service; disabled; vendor preset: enabled)
  +
Active: active (running) since Fri 2021-10-15 14:07:37 EEST; 21min ago
  +
Process: 19036 ExecStartPre=/usr/bin/env (code=exited, status=0/SUCCESS)
  +
Process: 19037 ExecStartPre=/bin/bash -c echo b=7d0758bee53b4ddbba5674ef66a7c067 (code=exited, status=0/SUCCESS)
  +
Process: 19038 ExecStartPre=/bin/bash -c echo g=root (code=exited, status=0/SUCCESS)
  +
Process: 19039 ExecStartPre=/bin/bash -c echo G=0 (code=exited, status=0/SUCCESS)
  +
Process: 19040 ExecStartPre=/bin/bash -c echo H=raspberrypi4 (code=exited, status=0/SUCCESS)
  +
Process: 19041 ExecStartPre=/bin/bash -c echo i= (code=exited, status=0/SUCCESS)
  +
Process: 19042 ExecStartPre=/bin/bash -c echo j=nginx (code=exited, status=0/SUCCESS)
  +
Process: 19043 ExecStartPre=/bin/bash -c echo m=f7cb830984574abd90d3b1a9616450f3 (code=exited, status=0/SUCCESS)
  +
Process: 19044 ExecStartPre=/bin/bash -c echo n=consul-template-vault-nginx.service (code=exited, status=0/SUCCESS)
  +
Process: 19045 ExecStartPre=/bin/bash -c echo N=consul-template-vault-nginx (code=exited, status=0/SUCCESS)
  +
Process: 19046 ExecStartPre=/bin/bash -c echo p=consul-template-vault-nginx (code=exited, status=0/SUCCESS)
  +
Process: 19047 ExecStartPre=/bin/bash -c echo u=root (code=exited, status=0/SUCCESS)
  +
Process: 19048 ExecStartPre=/bin/bash -c echo U=0 (code=exited, status=0/SUCCESS)
  +
Process: 19049 ExecStartPre=/bin/bash -c echo v=5.4.51-v7l+ (code=exited, status=0/SUCCESS)
  +
Process: 19050 ExecStartPre=/bin/bash -c echo % (code=exited, status=0/SUCCESS)
  +
Process: 19051 ExecStartPre=/bin/bash -c printf 'VAULT_TOKEN=' > /tmp/vault-token-consul-template-vault-nginx (code=exited, status=0/SUCCESS)
  +
Process: 19052 ExecStartPre=/bin/bash -c printf 'VAULT_TOKEN=' > /tmp/vault-token-consul-template-vault-nginx; /usr/local/vault/bin/vault login -method=userpass username=$VAULT_USERNAME password=$VAULT_PASSWORD --format=json | jq -r .auth.
  +
Process: 19064 ExecStartPre=/usr/bin/env (code=exited, status=0/SUCCESS)
  +
Main PID: 19065 (consul-template)
  +
Tasks: 13 (limit: 4915)
  +
CGroup: /system.slice/consul-template-vault-nginx.service
  +
└─19065 /usr/local/consul/bin/consul-template -config=/etc/consul-template.d/configs/nginx-vault.hcl
  +
  +
Oct 15 14:07:37 raspberrypi4 env[19064]: LANGUAGE=en_US.UTF-8
  +
Oct 15 14:07:37 raspberrypi4 env[19064]: LC_TIME=C.UTF-8
  +
Oct 15 14:07:37 raspberrypi4 env[19064]: PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
  +
Oct 15 14:07:37 raspberrypi4 env[19064]: INVOCATION_ID=01f3f30994c34ca6888059f640df7bce
  +
Oct 15 14:07:37 raspberrypi4 env[19064]: JOURNAL_STREAM=8:79140900
  +
Oct 15 14:07:37 raspberrypi4 env[19064]: VAULT_ADDR=http://127.0.0.1:8200
  +
Oct 15 14:07:37 raspberrypi4 env[19064]: VAULT_USERNAME=vault-dot-home-server-crt-user
  +
Oct 15 14:07:37 raspberrypi4 env[19064]: VAULT_PASSWORD=vault
  +
Oct 15 14:07:37 raspberrypi4 env[19064]: VAULT_TOKEN=s.tByQQL0DBdUjQH2lXAu2wuS8
  +
Oct 15 14:07:37 raspberrypi4 systemd[1]: Started consul-template for Nginx/Vault.
  +
</PRE>
  +
  +
==Проверка работы Nginx==
  +
===Без корневого сертификата===
  +
Ожидаемо - не работает
  +
<PRE>
  +
curl https://vault.home:8202 -v
  +
* Expire in 5 ms for 1 (transfer 0x1682880)
  +
* Trying 192.168.1.223...
  +
* TCP_NODELAY set
  +
* Expire in 200 ms for 4 (transfer 0x1682880)
  +
* Connected to vault.home (192.168.1.223) port 8202 (#0)
  +
* ALPN, offering h2
  +
* ALPN, offering http/1.1
  +
* successfully set certificate verify locations:
  +
* CAfile: none
  +
CApath: /etc/ssl/certs
  +
* TLSv1.3 (OUT), TLS handshake, Client hello (1):
  +
* TLSv1.3 (IN), TLS handshake, Server hello (2):
  +
* TLSv1.2 (IN), TLS handshake, Certificate (11):
  +
* TLSv1.2 (OUT), TLS alert, unknown CA (560):
  +
* SSL certificate problem: unable to get local issuer certificate
  +
* Closing connection 0
  +
curl: (60) SSL certificate problem: unable to get local issuer certificate
  +
More details here: https://curl.haxx.se/docs/sslcerts.html
  +
  +
curl failed to verify the legitimacy of the server and therefore could not
  +
establish a secure connection to it. To learn more about this situation and
  +
how to fix it, please visit the web page mentioned above.
  +
</PRE>
  +
  +
===Добавление корневого сертификата===
  +
* Внимание - расширение файла ВАЖНО для утилиты <B>update-ca-certificates</B>. Если оставить PEM то сертификат не будет добавлен.
  +
* <B>rootCA.pem</B> - файл корневого сертификата (см выше по тексту)
  +
* Корневой сертификат (НО НЕ КЛЮЧ!) всегда можно получить <B>curl http://vault.home:8200/v1/pki_root_ca/ca/pem </B>
  +
<PRE>
  +
cp rootCA.pem /usr/local/share/ca-certificates/rootCA.crt
  +
</PRE>
  +
  +
<PRE>
  +
update-ca-certificates
  +
Updating certificates in /etc/ssl/certs...
  +
1 added, 0 removed; done.
  +
Running hooks in /etc/ca-certificates/update.d...
  +
  +
Adding debian:rootCA.pem
  +
done.
  +
done.
  +
root@raspberrypi4:/usr/local/share/ca-certificates/extra#
  +
</PRE>
  +
  +
===С добавленным корневым сертификатом===
  +
Ожидаемо работает: (404 это НЕ ошибка SSL)
  +
<PRE>
  +
curl https://vault.home:8202
  +
404 page not found
  +
</PRE>
  +
===Проверка обновления сертефикатов===
  +
<PRE>
  +
while true; do echo "" | openssl s_client -connect vault.home:8202 > 111 2>/dev/null ; openssl x509 -in 111 -text -noout | grep -E 'Not [AB]'; sleep 30; done
  +
Not Before: Oct 15 11:55:07 2021 GMT
  +
Not After : Oct 15 11:57:35 2021 GMT
  +
Not Before: Oct 15 11:55:07 2021 GMT
  +
Not After : Oct 15 11:57:35 2021 GMT
  +
Not Before: Oct 15 11:55:07 2021 GMT
  +
Not After : Oct 15 11:57:35 2021 GMT
  +
Not Before: Oct 15 11:56:11 2021 GMT
  +
</PRE>
  +
  +
=Проверка отзыва сертификатов=
  +
TBD!
  +
  +
=Дополнения=
  +
==Параметры сертификатов==
  +
* <B>name</B> (string: <required>) – Specifies the name of the role to create. This is part of the request URL.
  +
  +
* <B>ttl</B> (string: "") – Specifies the Time To Live value provided as a string duration with time suffix. Hour is the largest suffix. If not set, uses the system default value or the value of max_ttl, whichever is shorter.
  +
  +
* <B>max_ttl</B> (string: "") – Specifies the maximum Time To Live provided as a string duration with time suffix. Hour is the largest suffix. If not set, defaults to the system maximum lease TTL.
  +
  +
* <B>allow_localhost</B> (bool: true) – Specifies if clients can request certificates for localhost as one of the requested common names. This is useful for testing and to allow clients on a single host to talk securely.
  +
  +
* <B>allowed_domains</B> (list: []) – Specifies the domains of the role. This is used with the allow_bare_domains and allow_subdomains options.
  +
  +
* <B>allowed_domains_template</B> ()bool: false) – When set, allowed_domains may contain templates, as with ACL Path Templating.
  +
  +
* <B>allow_bare_domains</B> (bool: false) – Specifies if clients can request certificates matching the value of the actual domains themselves; e.g. if a configured domain set with allowed_domains is example.com, this allows clients to actually request a certificate containing the name example.com as one of the DNS values on the final certificate. In some scenarios, this can be considered a security risk.
  +
  +
* <B>allow_subdomains</B> (bool: false) – Specifies if clients can request certificates with CNs that are subdomains of the CNs allowed by the other role options. This includes wildcard subdomains. For example, an allowed_domains value of example.com with this option set to true will allow foo.example.com and bar.example.com as well as *.example.com. This is redundant when using the allow_any_name option.
  +
  +
* <B>allow_glob_domains</B> (bool: false) - Allows names specified in allowed_domains to contain glob patterns (e.g. ftp*.example.com). Clients will be allowed to request certificates with names matching the glob patterns.
  +
  +
* <B>allow_any_name</B> (bool: false) – Specifies if clients can request any CN. Useful in some circumstances, but make sure you understand whether it is appropriate for your installation before enabling it.
  +
  +
* <B>enforce_hostnames</B> (bool: true) – Specifies if only valid host names are allowed for CNs, DNS SANs, and the host part of email addresses.
  +
  +
* <B>allow_ip_sans</B> (bool: true) – Specifies if clients can request IP Subject Alternative Names. No authorization checking is performed except to verify that the given values are valid IP addresses.
  +
  +
* <B>allowed_uri_sans</B> (string: "") - Defines allowed URI Subject Alternative Names. No authorization checking is performed except to verify that the given values are valid URIs. This can be a comma-delimited list or a JSON string slice. Values can contain glob patterns (e.g. spiffe://hostname/*).
  +
  +
* <B>allowed_other_sans</B> (string: "") – Defines allowed custom OID/UTF8-string SANs. This can be a comma-delimited list or a JSON string slice, where each element has the same format as OpenSSL: <oid>;<type>:<value>, but the only valid type is UTF8 or UTF-8. The value part of an element may be a * to allow any value with that OID. Alternatively, specifying a single * will allow any other_sans input.
  +
  +
* <B>server_flag</B> (bool: true) – Specifies if certificates are flagged for server use.
  +
  +
* <B>client_flag</B> (bool: true) – Specifies if certificates are flagged for client use.
  +
  +
* <B>code_signing_flag</B> (bool: false) – Specifies if certificates are flagged for code signing use.
  +
  +
* <B>email_protection_flag</B> (bool: false) – Specifies if certificates are flagged for email protection use.
  +
  +
* <B>key_type</B> (string: "rsa") – Specifies the type of key to generate for generated private keys and the type of key expected for submitted CSRs. Currently, rsa and ec are supported, or when signing CSRs any can be specified to allow keys of either type and with any bit size (subject to > 1024 bits for RSA keys).
  +
  +
* <B>key_bits</B> (int: 2048) – Specifies the number of bits to use for the generated keys. This will need to be changed for ec keys, e.g., 224, 256, 384 or 521.
  +
  +
* <B>key_usage</B> (list: ["DigitalSignature", "KeyAgreement", "KeyEncipherment"]) – Specifies the allowed key usage constraint on issued certificates. Valid values can be found at https://golang.org/pkg/crypto/x509/#KeyUsage - simply drop the KeyUsage part of the value. Values are not case-sensitive. To specify no key usage constraints, set this to an empty list.
  +
  +
* <B>ext_key_usage</B> (list: []) – Specifies the allowed extended key usage constraint on issued certificates. Valid values can be found at https://golang.org/pkg/crypto/x509/#ExtKeyUsage - simply drop the ExtKeyUsage part of the value. Values are not case-sensitive. To specify no key usage constraints, set this to an empty list.
  +
  +
* <B>ext_key_usage_oids</B> (string: "") - A comma-separated string or list of extended key usage oids.
  +
  +
* <B>use_csr_common_name</B> (bool: true) – When used with the CSR signing endpoint, the common name in the CSR will be used instead of taken from the JSON data. This does not include any requested SANs in the CSR; use use_csr_sans for that.
  +
  +
* <B>use_csr_sans</B> (bool: true) – When used with the CSR signing endpoint, the subject alternate names in the CSR will be used instead of taken from the JSON data. This does not include the common name in the CSR; use use_csr_common_name for that.
  +
  +
* <B>ou</B> (string: "") – Specifies the OU (OrganizationalUnit) values in the subject field of issued certificates. This is a comma-separated string or JSON array.
  +
  +
* <B>organization</B> (string: "") – Specifies the O (Organization) values in the subject field of issued certificates. This is a comma-separated string or JSON array.
  +
  +
* <B>country</B> (string: "") – Specifies the C (Country) values in the subject field of issued certificates. This is a comma-separated string or JSON array.
  +
  +
* <B>locality</B> (string: "") – Specifies the L (Locality) values in the subject field of issued certificates. This is a comma-separated string or JSON array.
  +
  +
* <B>province</B> (string: "") – Specifies the ST (Province) values in the subject field of issued certificates. This is a comma-separated string or JSON array.
  +
  +
* <B>street_address</B> (string: "") – Specifies the Street Address values in the subject field of issued certificates. This is a comma-separated string or JSON array.
  +
  +
* <B>postal_code</B> (string: "") – Specifies the Postal Code values in the subject field of issued certificates. This is a comma-separated string or JSON array.
  +
  +
* <B>serial_number</B> (string: "") – Specifies the Serial Number, if any. Otherwise Vault will generate a random serial for you. If you want more than one, specify alternative names in the alt_names map using OID 2.5.4.5.
  +
  +
* <B>generate_lease</B> (bool: false) – Specifies if certificates issued/signed against this role will have Vault leases attached to them. Certificates can be added to the CRL by vault revoke <lease_id> when certificates are associated with leases. It can also be done using the pki/revoke endpoint. However, when lease generation is disabled, invoking pki/revoke would be the only way to add the certificates to the CRL.
  +
  +
* <B>no_store</B> (bool: false) – If set, certificates issued/signed against this role will not be stored in the storage backend. This can improve performance when issuing large numbers of certificates. However, certificates issued in this way cannot be enumerated or revoked, so this option is recommended only for certificates that are non-sensitive, or extremely short-lived. This option implies a value of false for generate_lease.
  +
  +
* <B>require_cn</B> (bool: true) - If set to false, makes the common_name field optional while generating a certificate.
  +
  +
* <B>policy_identifiers</B> (list: []) – A comma-separated string or list of policy OIDs.
  +
  +
* <B>basic_constraints_valid_for_non_ca</B> (bool: false) - Mark Basic Constraints valid when issuing non-CA certificates.
  +
  +
* <B>not_before_duration</B> (duration: "30s") – Specifies the duration by which to backdate the NotBefore property.
  +
  +
=Ссылки=
  +
==Русскоязычные==
  +
* О ограничениях накладывемых на сертефикаты https://www.sysadmins.lv/blog-ru/znakomtes-basic-constraints.aspx
  +
* https://pro-ldap.ru/tr/zytrax/tech/ssl.html
  +
* https://sgolubev.ru/openssl-ca/
  +
* На русском с минимальными пояснениями: https://itdraft.ru/2020/12/02/hashicorp-vault-kak-czentr-sertifikaczii-ca-vault-pki/
  +
  +
===Vault===
  +
* https://russianblogs.com/article/8543260210/
  +
* https://itdraft.ru/2020/12/02/hashicorp-vault-kak-czentr-sertifikaczii-ca-vault-pki/
  +
  +
==Прочие==
  +
* https://www.vaultproject.io/docs/secrets/pki
  +
* https://learn.hashicorp.com/tutorials/vault/pki-engine
  +
* https://stackoverflow.com/questions/10175812/how-to-generate-a-self-signed-ssl-certificate-using-openssl
  +
* https://medium.com/hashicorp-engineering/pki-as-a-service-with-hashicorp-vault-a8d075ece9a

Текущая версия на 09:51, 23 сентября 2022


Vault PKI

OpenSSL это очень просто (нет)

Развертывание PKI на основе Vault

Установка Vault

Предполагается что Vault уже установлен и настроен

PKI

Логика работы (кратко)

  • Создается несколько инстансов PKI внутри одного процесса Vault (для большей безопастности)
  • Корневой сертефикат выписывается корневым PKI
    • Кроме прочего - он может быть удален из волта, закрыт в сейфе и т п для безопастности так как используется только для создания промежуточного СА
  • этот сертификат (он НЕ является секретным) распространяется по всем нодам и используется для проверки
  • этим сертификатом подписвается промежуточный CA
  • промежуточный CA подписывает клиентские сертификаты

Кроме того можно удлинить эту цепочку используя уже готовый СА и промежуточный СА и импортировав их в Vault (но примера тут нет - я не делал)

Включить PKI для корневого сертификата

vault secrets enable \
    -path=pki_root_ca \
    -description="PKI Root CA" \
    -max-lease-ttl="262800h" \
    pki

Создание корневого сертефиката (CA)

Конфигурация Vault

  • ВАЖНО: Тип определяет будет ли показан ключ от сертификата. В случае internal ключ показа не будет и сертификат можно будет использовать только в Vault
TYPE="exported"
#TYPE="internal"

vault write -format=json pki_root_ca/root/generate/${TYPE} \
    common_name="Root Certificate Authority for Home Network" \
    country="Ukraine" \
    locality="Kharkov" \
    street_address="Lui Pastera St. 322, app. 131" \
    postal_code="61172" \
    organization="Home Network" \
    ou="IT" \
    ttl="262800h" > pki-root-ca.json

Просмотр результата

Результат работы команды (длинный вывод пропущен):

cat pki-root-ca.json
{
  "request_id": "3d05280b-25db-6834-1472-abe11fb6c4ab",
  "lease_id": "",
  "lease_duration": 0,
  "renewable": false,
  "data": {
    "certificate": "-----BEGIN CERTIFICATE-----<SKIP>F72Cwqh1wTUNHHEJKMupiTIs2B\nsjCYRMVUw1A6MBY5kS8KrTizRMIZCLKjSQoVY4F8Y7lMjnw=\n-----END CERTIFICATE-----",
    "expiration": 2579950707,
    "issuing_ca": "-----BEGIN CERTIFICATE-----<SKIP>F72Cwqh1wTUNHHEJKMupiTIs2B\nsjCYRMVUw1A6MBY5kS8KrTizRMIZCLKjSQoVY4F8Y7lMjnw=\n-----END CERTIFICATE-----",
    "private_key": "-----BEGIN RSA PRIVATE KEY-----<SKIP>hwmKMhs+HI2Hs\nflcrSqLT26ccUb5bMRtXJ1pYrnjwOJnV/4GAJ5QG4aGNGdK/jIF9XbE=\n-----END RSA PRIVATE KEY-----",
    "private_key_type": "rsa",
    "serial_number": "05:55:c5:9b:20:91:66:86:96:42:84:bd:66:9a:c1:70:28:8d:bf:82"
  },
  "warnings": null
}

Корневой сертефикат самоподписаный. Поля certificate и issuing_ca полностью совпадают.

Подготовка файлов с сертефикатом и ключем

cat pki-root-ca.json | jq -r .data.certificate > rootCA.pem
cat pki-root-ca.json | jq -r .data.issuing_ca > rootCA_issuing_ca.pem
cat pki-root-ca.json | jq -r .data.private_key > rootCA_private_key.pem
openssl  x509 -in rootCA.pem -text -noout
Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number:
            05:55:c5:9b:20:91:66:86:96:42:84:bd:66:9a:c1:70:28:8d:bf:82
        Signature Algorithm: sha256WithRSAEncryption
        Issuer: C = Ukraine, L = Kharkov, street = app. 131 + street = Lui Pastera St. 322, postalCode = 61172, O = Home Network, OU = IT, CN = Root Certificate Authority for Home Network
        Validity
            Not Before: Oct 10 12:58:00 2021 GMT
            Not After : Oct  3 12:58:27 2051 GMT
        Subject: C = Ukraine, L = Kharkov, street = app. 131 + street = Lui Pastera St. 322, postalCode = 61172, O = Home Network, OU = IT, CN = Root Certificate Authority for Home Network
        Subject Public Key Info:
            Public Key Algorithm: rsaEncryption
                RSA Public-Key: (2048 bit)
                Modulus:
                    00:be:dc:02:4a:f5:32:38:b2:cf:10:4f:78:d0:de:
                    d0:82:0e:52:2b:7f:ab:d9:ee:5c:a0:81:4a:8c:2d:
                    ae:60:ac:27:6c:12:ef:a6:6f:6f:62:23:74:d0:c2:
                    d5:b8:83:80:66:a1:50:ea:58:ea:18:b3:17:49:a6:
                    6d:83:b9:d3:0b:a5:20:c1:5c:5a:54:d6:40:56:c1:
                    c4:60:59:b9:0b:fd:de:0c:d4:0b:03:7a:93:cd:f0:
                    1f:94:25:ee:11:07:86:74:f3:e8:31:e5:66:99:4e:
                    03:a0:89:ca:3e:8b:65:73:39:d8:69:91:c0:13:ba:
                    6e:35:2a:60:e7:d9:e6:5b:53:ee:bd:12:4a:ba:1a:
                    d0:70:60:e2:65:dc:52:9d:f8:cc:0c:ec:ff:db:d5:
                    e3:12:a7:a0:91:04:a2:40:01:f3:1c:e4:5a:93:74:
                    37:16:3c:e1:bf:22:fe:0a:a1:dd:ee:cd:37:2b:6f:
                    29:47:14:b5:1b:66:57:98:b5:7e:02:b5:4b:54:ee:
                    b4:e9:93:fa:c9:ed:4e:28:cc:dc:ab:68:42:fd:f7:
                    c0:ee:89:15:2e:46:76:64:f8:ac:be:86:1d:54:4a:
                    4a:29:d5:2d:71:59:34:f8:f0:0b:e5:fc:1c:14:11:
                    d8:08:8b:79:0a:a7:8f:6b:61:30:b3:69:9a:90:12:
                    c3:29
                Exponent: 65537 (0x10001)
        X509v3 extensions:
            X509v3 Key Usage: critical
                Certificate Sign, CRL Sign
            X509v3 Basic Constraints: critical
                CA:TRUE
            X509v3 Subject Key Identifier:
                DB:3A:73:7A:03:25:2E:17:48:46:58:67:19:AD:86:2E:04:3D:EB:EC
            X509v3 Authority Key Identifier:
                keyid:DB:3A:73:7A:03:25:2E:17:48:46:58:67:19:AD:86:2E:04:3D:EB:EC

    Signature Algorithm: sha256WithRSAEncryption
         71:6f:56:d4:6a:b8:24:9d:fc:16:47:8c:1c:59:ac:c2:92:90:
         36:5f:ef:73:43:c7:d7:2e:20:b4:4b:e9:3f:57:b4:a6:b4:82:
         a2:28:bd:f2:98:07:a1:49:df:c7:1d:60:5a:56:fc:85:64:e7:
         d8:97:75:f6:36:66:1a:04:ab:57:8a:43:d8:3c:aa:97:72:5e:
         3d:85:59:d9:d3:b6:2b:d5:aa:d6:49:ad:35:04:2c:22:52:9c:
         61:6a:6b:2f:dd:ba:78:cc:b7:ac:9c:fa:6d:1e:57:62:8f:b8:
         94:f9:98:30:d5:c1:06:24:c0:17:58:46:fd:6e:55:92:6f:98:
         11:d8:cd:28:6f:92:cb:90:5d:5e:91:b3:aa:bb:fd:d0:f5:32:
         9a:ed:a4:80:5a:7e:e6:6b:5d:98:19:71:04:86:de:18:e2:38:
         37:0f:e2:61:0a:d3:81:c0:06:1f:e7:f0:a0:c5:8f:f7:90:8f:
         c9:74:d5:68:1d:33:b4:a5:45:fc:f7:8c:35:a6:3a:1d:a7:6a:
         11:a5:1b:e1:7b:d8:2c:2a:87:5c:13:50:d1:c7:10:92:8c:ba:
         98:93:22:cd:81:b2:30:98:44:c5:54:c3:50:3a:30:16:39:91:
         2f:0a:ad:38:b3:44:c2:19:08:b2:a3:49:0a:15:63:81:7c:63:
         b9:4c:8e:7c

URL для корневого CA

Публикуем URL’ы для корневого центра сертификации

vault write pki_root_ca/config/urls \
  issuing_certificates="http://vault.home:8200/v1/pki_root_ca/ca" \
  crl_distribution_points="http://vault.home:8200/v1/pki_root_ca/crl

Создание промежуточного СА

В целом можно использовать и корневой СА для создания конечных сертификатов но "лучшие собаководы" рекомендуют использовать промежуточный CA

Конфигурация Vault

vault secrets enable \
    -path=pki_intermediate_ca \
    -description="PKI Intermediate CA" \
    -max-lease-ttl="175200h" \
    pki
Success! Enabled the pki secrets engine at: pki_intermediate_ca/


Генерация запроса на сертификат для промежуточного CA

vault write -format=json pki_intermediate_ca/intermediate/generate/internal \
   common_name="Intermediate CA" \
   country="Ukraine" \
   locality="Kharkov" \
   street_address="Lui Pastera st. 322 app. 131" \
   postal_code="101000" \
   organization="Horns and Hooves LLC" \
   ou="IT" \
   ttl="175200h" > pki_intermediate_ca.csr.json

Просмотр результатов

Сырой вывод
{
  "request_id": "2e544789-ed06-1d6f-97cf-928c1fb54e77",
  "lease_id": "",
  "lease_duration": 0,
  "renewable": false,
  "data": {
    "csr": "-----BEGIN CERTIFICATE REQUEST-----\nMIIC6DCCAdACAQAwgaIxEDAOBgNVBAYTB1VrcmFpbmUxEDAOBgNVBAcTB0toYXJr\nb3YxJTAjBgNVBAkTHEx1aSBQYXN0ZXJhIHN0LiAzMjIgYXBwLiAxMzExDzANBgNV\nBBETBjEwMTAwMDEdMBsGA1UEChMUSG9ybnMgYW5kIEhvb3ZlcyBMTEMxCzAJBgNV\nBAsTAklUMRgwFgYDVQQDEw9JbnRlcm1lZGlhdGUgQ0EwggEiMA0GCSqGSIb3DQEB\nAQUAA4IBDwAwggEKAoIBAQDIJlmWRZBXLgMymWtlUCn9+3I1BS1W+Kyya2Tguc9R\nblhcyjzb1DshtkJAdohm3bwPnECCPyC3ARKOyN8xrepYOlphsn3+L3tpjOfvq7TS\nJXl194gjkURG7Ahz2FB/oPq0+d9YLYB/TTCh2H2r+3kXMX+ByJTcIHQ+03+6Er73\n+f0qOmYyy/U61lmjYGQTzlhLxzBWZ1xvLNJKaMGoZHgDyJ15bLyCcuSp0GYFnBht\nwvS3BL6wvuhon5NBTjLdnPRzYA8sbPq0SVppUQydaVY3vdBG3HsoWq2d9hQs6c56\nUyspaxpskKjpEdpSp///jfQ2cHAup4AeQBQaine+EfzFAgMBAAGgADANBgkqhkiG\n9w0BAQsFAAOCAQEAmhSXiyvK9J1ZarDQOx5XpPRZ+IfjvYhwcxJ5eBgVcJCljcpr\nAPSvc6dt9di9vHoT/YQ43t47bV0hxVxKERNfOHCjX9VuruOdJ5WE3ptRx0oQsMdC\nbuIxQv/j4F4+kZmLDiUfTsOVTGuOKVqPJ3nyMibeE0JhQHu58hprAosDc2kzFf31\n3KOrQHhpITVgGGPqM4VI/w7ghIzxL/qvPCMX3Qshe5lkHY1jTNt6zHeofC0QRIdo\n2P0Iteb0rR59+B1Bq+jBoKTFmyv1AKifeSY6syTpbp/rKyzeY8pe/txx3JOfF29K\nwMjCLShOPDmOmPPUCbq/vRTUl9zMBsC7tKYRbA==\n-----END CERTIFICATE REQUEST-----"
  },
  "warnings": null
}
Сохранить запрос в файл
cat pki_intermediate_ca.csr.json | jq -r .data.csr
-----BEGIN CERTIFICATE REQUEST-----
MIIC6DCCAdACAQAwgaIxEDAOBgNVBAYTB1VrcmFpbmUxEDAOBgNVBAcTB0toYXJr
b3YxJTAjBgNVBAkTHEx1aSBQYXN0ZXJhIHN0LiAzMjIgYXBwLiAxMzExDzANBgNV
BBETBjEwMTAwMDEdMBsGA1UEChMUSG9ybnMgYW5kIEhvb3ZlcyBMTEMxCzAJBgNV
BAsTAklUMRgwFgYDVQQDEw9JbnRlcm1lZGlhdGUgQ0EwggEiMA0GCSqGSIb3DQEB
AQUAA4IBDwAwggEKAoIBAQDIJlmWRZBXLgMymWtlUCn9+3I1BS1W+Kyya2Tguc9R
blhcyjzb1DshtkJAdohm3bwPnECCPyC3ARKOyN8xrepYOlphsn3+L3tpjOfvq7TS
JXl194gjkURG7Ahz2FB/oPq0+d9YLYB/TTCh2H2r+3kXMX+ByJTcIHQ+03+6Er73
+f0qOmYyy/U61lmjYGQTzlhLxzBWZ1xvLNJKaMGoZHgDyJ15bLyCcuSp0GYFnBht
wvS3BL6wvuhon5NBTjLdnPRzYA8sbPq0SVppUQydaVY3vdBG3HsoWq2d9hQs6c56
UyspaxpskKjpEdpSp///jfQ2cHAup4AeQBQaine+EfzFAgMBAAGgADANBgkqhkiG
9w0BAQsFAAOCAQEAmhSXiyvK9J1ZarDQOx5XpPRZ+IfjvYhwcxJ5eBgVcJCljcpr
APSvc6dt9di9vHoT/YQ43t47bV0hxVxKERNfOHCjX9VuruOdJ5WE3ptRx0oQsMdC
buIxQv/j4F4+kZmLDiUfTsOVTGuOKVqPJ3nyMibeE0JhQHu58hprAosDc2kzFf31
3KOrQHhpITVgGGPqM4VI/w7ghIzxL/qvPCMX3Qshe5lkHY1jTNt6zHeofC0QRIdo
2P0Iteb0rR59+B1Bq+jBoKTFmyv1AKifeSY6syTpbp/rKyzeY8pe/txx3JOfF29K
wMjCLShOPDmOmPPUCbq/vRTUl9zMBsC7tKYRbA==
-----END CERTIFICATE REQUEST-----
openssl req  -in pki_intermediate_ca.csr -text -noout
Certificate Request:
    Data:
        Version: 1 (0x0)
        Subject: C = Ukraine, L = Kharkov, street = Lui Pastera st. 322 app. 131, postalCode = 101000, O = Horns and Hooves LLC, OU = IT, CN = Intermediate CA
        Subject Public Key Info:
            Public Key Algorithm: rsaEncryption
                RSA Public-Key: (2048 bit)
                Modulus:
                    00:c8:26:59:96:45:90:57:2e:03:32:99:6b:65:50:
                    29:fd:fb:72:35:05:2d:56:f8:ac:b2:6b:64:e0:b9:
                    cf:51:6e:58:5c:ca:3c:db:d4:3b:21:b6:42:40:76:
                    88:66:dd:bc:0f:9c:40:82:3f:20:b7:01:12:8e:c8:
                    df:31:ad:ea:58:3a:5a:61:b2:7d:fe:2f:7b:69:8c:
                    e7:ef:ab:b4:d2:25:79:75:f7:88:23:91:44:46:ec:
                    08:73:d8:50:7f:a0:fa:b4:f9:df:58:2d:80:7f:4d:
                    30:a1:d8:7d:ab:fb:79:17:31:7f:81:c8:94:dc:20:
                    74:3e:d3:7f:ba:12:be:f7:f9:fd:2a:3a:66:32:cb:
                    f5:3a:d6:59:a3:60:64:13:ce:58:4b:c7:30:56:67:
                    5c:6f:2c:d2:4a:68:c1:a8:64:78:03:c8:9d:79:6c:
                    bc:82:72:e4:a9:d0:66:05:9c:18:6d:c2:f4:b7:04:
                    be:b0:be:e8:68:9f:93:41:4e:32:dd:9c:f4:73:60:
                    0f:2c:6c:fa:b4:49:5a:69:51:0c:9d:69:56:37:bd:
                    d0:46:dc:7b:28:5a:ad:9d:f6:14:2c:e9:ce:7a:53:
                    2b:29:6b:1a:6c:90:a8:e9:11:da:52:a7:ff:ff:8d:
                    f4:36:70:70:2e:a7:80:1e:40:14:1a:8a:77:be:11:
                    fc:c5
                Exponent: 65537 (0x10001)
        Attributes:
            a0:00
    Signature Algorithm: sha256WithRSAEncryption
         9a:14:97:8b:2b:ca:f4:9d:59:6a:b0:d0:3b:1e:57:a4:f4:59:
         f8:87:e3:bd:88:70:73:12:79:78:18:15:70:90:a5:8d:ca:6b:
         00:f4:af:73:a7:6d:f5:d8:bd:bc:7a:13:fd:84:38:de:de:3b:
         6d:5d:21:c5:5c:4a:11:13:5f:38:70:a3:5f:d5:6e:ae:e3:9d:
         27:95:84:de:9b:51:c7:4a:10:b0:c7:42:6e:e2:31:42:ff:e3:
         e0:5e:3e:91:99:8b:0e:25:1f:4e:c3:95:4c:6b:8e:29:5a:8f:
         27:79:f2:32:26:de:13:42:61:40:7b:b9:f2:1a:6b:02:8b:03:
         73:69:33:15:fd:f5:dc:a3:ab:40:78:69:21:35:60:18:63:ea:
         33:85:48:ff:0e:e0:84:8c:f1:2f:fa:af:3c:23:17:dd:0b:21:
         7b:99:64:1d:8d:63:4c:db:7a:cc:77:a8:7c:2d:10:44:87:68:
         d8:fd:08:b5:e6:f4:ad:1e:7d:f8:1d:41:ab:e8:c1:a0:a4:c5:
         9b:2b:f5:00:a8:9f:79:26:3a:b3:24:e9:6e:9f:eb:2b:2c:de:
         63:ca:5e:fe:dc:71:dc:93:9f:17:6f:4a:c0:c8:c2:2d:28:4e:
         3c:39:8e:98:f3:d4:09:ba:bf:bd:14:d4:97:dc:cc:06:c0:bb:
         b4:a6:11:6c

Генерация сертификата по запросу

  • @pki_intermediate_ca.csr - имя файла

Создание сертефиката

vault write -format=json pki_root_ca/root/sign-intermediate csr=@pki_intermediate_ca.csr \
   country="Ukraine" \
   locality="Kharkov" \
   street_address="Lui Pastera st. 322 app. 131" \
   postal_code="61172" \
   organization="Home Network" \
   ou="IT" \
   format=pem_bundle \
   ttl="175200h" > intermediateCA.cert.pem.json

"Сырой" результат

{
  "request_id": "79f389eb-be78-dff6-e1b5-71034dc5fd87",
  "lease_id": "",
  "lease_duration": 0,
  "renewable": false,
  "data": {
    "certificate": "-----BEGIN CERTIFICATE-----\nMIIESTCCAzGgAwIBAgIUQLKqMu7qL4R1u4/sLphWcBxm9g0wDQYJKoZIhvcNAQEL\nBQAwgb0xEDAOBgNVBAYTB1VrcmFpbmUxEDAOBgNVBAcTB0toYXJrb3YxLTAPBgNV\nBAkTCGFwcC4gMTMxMBoGA1UECRMTTHVpIFBhc3RlcmEgU3QuIDMyMjEOMAwGA1UE\nERMFNjExNzIxFTATBgNVBAoTDEhvbWUgTmV0d29yazELMAkGA1UECxMCSVQxNDAy\nBgNVBAMTK1Jvb3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5IGZvciBIb21lIE5ldHdv\ncmswHhcNMjExMDExMDkyMjM3WhcNNDExMDA2MDkyMzA3WjCBmTEQMA4GA1UEBhMH\nVWtyYWluZTEQMA4GA1UEBxMHS2hhcmtvdjElMCMGA1UECRMcTHVpIFBhc3RlcmEg\nc3QuIDMyMiBhcHAuIDEzMTEOMAwGA1UEERMFNjExNzIxFTATBgNVBAoTDEhvbWUg\nTmV0d29yazELMAkGA1UECxMCSVQxGDAWBgNVBAMTD0ludGVybWVkaWF0ZSBDQTCC\nASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMgmWZZFkFcuAzKZa2VQKf37\ncjUFLVb4rLJrZOC5z1FuWFzKPNvUOyG2QkB2iGbdvA+cQII/ILcBEo7I3zGt6lg6\nWmGyff4ve2mM5++rtNIleXX3iCORREbsCHPYUH+g+rT531gtgH9NMKHYfav7eRcx\nf4HIlNwgdD7Tf7oSvvf5/So6ZjLL9TrWWaNgZBPOWEvHMFZnXG8s0kpowahkeAPI\nnXlsvIJy5KnQZgWcGG3C9LcEvrC+6Gifk0FOMt2c9HNgDyxs+rRJWmlRDJ1pVje9\n0EbceyharZ32FCzpznpTKylrGmyQqOkR2lKn//+N9DZwcC6ngB5AFBqKd74R/MUC\nAwEAAaNjMGEwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0O\nBBYEFFfMF8/PIZRxQrirBnz9/EVt+WpPMB8GA1UdIwQYMBaAFNs6c3oDJS4XSEZY\nZxmthi4EPevsMA0GCSqGSIb3DQEBCwUAA4IBAQCI5j1vsxGmb2zhd1p7rLJibntp\nJHxTg0qG9pDKzO3erUDia53ifTRchRjNqgcdTJO89MbCVpMcK88+E01X3KtGZMFR\n3V4I1Gmptdg4luicYzrO92S40CiRHr9UFz8Cftg9JxGZAk0MN3ScpjtxPM1fZs4d\n2INtQtyjtZ/I86itogPsKHo7hrIdo9IGmFa7OHuul/uYl3Z9cNLOAEHcBFarQ9Vn\nvQmPpdaq3t4ArwFHRrn5ZMgM9HbvRbgr3ns5U4uX9TdSefHashoAuVGvIFquMpVj\n0ajUAed1yuVd7S2USE1s8RyN7j3t0D7FG7pRECTBnZYKqBc7OI2YdiwdPvQH\n-----END CERTIFICATE-----",
    "expiration": 2264664187,
    "issuing_ca": "-----BEGIN CERTIFICATE-----\nMIIEbzCCA1egAwIBAgIUBVXFmyCRZoaWQoS9ZprBcCiNv4IwDQYJKoZIhvcNAQEL\nBQAwgb0xEDAOBgNVBAYTB1VrcmFpbmUxEDAOBgNVBAcTB0toYXJrb3YxLTAPBgNV\nBAkTCGFwcC4gMTMxMBoGA1UECRMTTHVpIFBhc3RlcmEgU3QuIDMyMjEOMAwGA1UE\nERMFNjExNzIxFTATBgNVBAoTDEhvbWUgTmV0d29yazELMAkGA1UECxMCSVQxNDAy\nBgNVBAMTK1Jvb3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5IGZvciBIb21lIE5ldHdv\ncmswIBcNMjExMDEwMTI1ODAwWhgPMjA1MTEwMDMxMjU4MjdaMIG9MRAwDgYDVQQG\nEwdVa3JhaW5lMRAwDgYDVQQHEwdLaGFya292MS0wDwYDVQQJEwhhcHAuIDEzMTAa\nBgNVBAkTE0x1aSBQYXN0ZXJhIFN0LiAzMjIxDjAMBgNVBBETBTYxMTcyMRUwEwYD\nVQQKEwxIb21lIE5ldHdvcmsxCzAJBgNVBAsTAklUMTQwMgYDVQQDEytSb290IENl\ncnRpZmljYXRlIEF1dGhvcml0eSBmb3IgSG9tZSBOZXR3b3JrMIIBIjANBgkqhkiG\n9w0BAQEFAAOCAQ8AMIIBCgKCAQEAvtwCSvUyOLLPEE940N7Qgg5SK3+r2e5coIFK\njC2uYKwnbBLvpm9vYiN00MLVuIOAZqFQ6ljqGLMXSaZtg7nTC6UgwVxaVNZAVsHE\nYFm5C/3eDNQLA3qTzfAflCXuEQeGdPPoMeVmmU4DoInKPotlcznYaZHAE7puNSpg\n59nmW1PuvRJKuhrQcGDiZdxSnfjMDOz/29XjEqegkQSiQAHzHORak3Q3FjzhvyL+\nCqHd7s03K28pRxS1G2ZXmLV+ArVLVO606ZP6ye1OKMzcq2hC/ffA7okVLkZ2ZPis\nvoYdVEpKKdUtcVk0+PAL5fwcFBHYCIt5CqePa2Ews2makBLDKQIDAQABo2MwYTAO\nBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQU2zpzegMl\nLhdIRlhnGa2GLgQ96+wwHwYDVR0jBBgwFoAU2zpzegMlLhdIRlhnGa2GLgQ96+ww\nDQYJKoZIhvcNAQELBQADggEBAHFvVtRquCSd/BZHjBxZrMKSkDZf73NDx9cuILRL\n6T9XtKa0gqIovfKYB6FJ38cdYFpW/IVk59iXdfY2ZhoEq1eKQ9g8qpdyXj2FWdnT\ntivVqtZJrTUELCJSnGFqay/dunjMt6yc+m0eV2KPuJT5mDDVwQYkwBdYRv1uVZJv\nmBHYzShvksuQXV6Rs6q7/dD1MprtpIBafuZrXZgZcQSG3hjiODcP4mEK04HABh/n\n8KDFj/eQj8l01WgdM7SlRfz3jDWmOh2nahGlG+F72Cwqh1wTUNHHEJKMupiTIs2B\nsjCYRMVUw1A6MBY5kS8KrTizRMIZCLKjSQoVY4F8Y7lMjnw=\n-----END CERTIFICATE-----",
    "serial_number": "40:b2:aa:32:ee:ea:2f:84:75:bb:8f:ec:2e:98:56:70:1c:66:f6:0d"
  },
  "warnings": null
}

PEM Файл

cat intermediateCA.cert.pem.json | jq -r .data.certificate > intermediateCA.cert.pem
-----BEGIN CERTIFICATE-----
MIIESTCCAzGgAwIBAgIUQLKqMu7qL4R1u4/sLphWcBxm9g0wDQYJKoZIhvcNAQEL
BQAwgb0xEDAOBgNVBAYTB1VrcmFpbmUxEDAOBgNVBAcTB0toYXJrb3YxLTAPBgNV
BAkTCGFwcC4gMTMxMBoGA1UECRMTTHVpIFBhc3RlcmEgU3QuIDMyMjEOMAwGA1UE
ERMFNjExNzIxFTATBgNVBAoTDEhvbWUgTmV0d29yazELMAkGA1UECxMCSVQxNDAy
BgNVBAMTK1Jvb3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5IGZvciBIb21lIE5ldHdv
cmswHhcNMjExMDExMDkyMjM3WhcNNDExMDA2MDkyMzA3WjCBmTEQMA4GA1UEBhMH
VWtyYWluZTEQMA4GA1UEBxMHS2hhcmtvdjElMCMGA1UECRMcTHVpIFBhc3RlcmEg
c3QuIDMyMiBhcHAuIDEzMTEOMAwGA1UEERMFNjExNzIxFTATBgNVBAoTDEhvbWUg
TmV0d29yazELMAkGA1UECxMCSVQxGDAWBgNVBAMTD0ludGVybWVkaWF0ZSBDQTCC
ASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMgmWZZFkFcuAzKZa2VQKf37
cjUFLVb4rLJrZOC5z1FuWFzKPNvUOyG2QkB2iGbdvA+cQII/ILcBEo7I3zGt6lg6
WmGyff4ve2mM5++rtNIleXX3iCORREbsCHPYUH+g+rT531gtgH9NMKHYfav7eRcx
f4HIlNwgdD7Tf7oSvvf5/So6ZjLL9TrWWaNgZBPOWEvHMFZnXG8s0kpowahkeAPI
nXlsvIJy5KnQZgWcGG3C9LcEvrC+6Gifk0FOMt2c9HNgDyxs+rRJWmlRDJ1pVje9
0EbceyharZ32FCzpznpTKylrGmyQqOkR2lKn//+N9DZwcC6ngB5AFBqKd74R/MUC
AwEAAaNjMGEwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0O
BBYEFFfMF8/PIZRxQrirBnz9/EVt+WpPMB8GA1UdIwQYMBaAFNs6c3oDJS4XSEZY
Zxmthi4EPevsMA0GCSqGSIb3DQEBCwUAA4IBAQCI5j1vsxGmb2zhd1p7rLJibntp
JHxTg0qG9pDKzO3erUDia53ifTRchRjNqgcdTJO89MbCVpMcK88+E01X3KtGZMFR
3V4I1Gmptdg4luicYzrO92S40CiRHr9UFz8Cftg9JxGZAk0MN3ScpjtxPM1fZs4d
2INtQtyjtZ/I86itogPsKHo7hrIdo9IGmFa7OHuul/uYl3Z9cNLOAEHcBFarQ9Vn
vQmPpdaq3t4ArwFHRrn5ZMgM9HbvRbgr3ns5U4uX9TdSefHashoAuVGvIFquMpVj
0ajUAed1yuVd7S2USE1s8RyN7j3t0D7FG7pRECTBnZYKqBc7OI2YdiwdPvQH
-----END CERTIFICATE-----

Детали сертефиката

openssl x509 -in intermediateCA.cert.pem -noout -text
Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number:
            40:b2:aa:32:ee:ea:2f:84:75:bb:8f:ec:2e:98:56:70:1c:66:f6:0d
        Signature Algorithm: sha256WithRSAEncryption
        Issuer: C = Ukraine, L = Kharkov, street = app. 131 + street = Lui Pastera St. 322, postalCode = 61172, O = Home Network, OU = IT, CN = Root Certificate Authority for Home Network
        Validity
            Not Before: Oct 11 09:22:37 2021 GMT
            Not After : Oct  6 09:23:07 2041 GMT
        Subject: C = Ukraine, L = Kharkov, street = Lui Pastera st. 322 app. 131, postalCode = 61172, O = Home Network, OU = IT, CN = Intermediate CA
        Subject Public Key Info:
            Public Key Algorithm: rsaEncryption
                RSA Public-Key: (2048 bit)
                Modulus:
                    00:c8:26:59:96:45:90:57:2e:03:32:99:6b:65:50:
                    29:fd:fb:72:35:05:2d:56:f8:ac:b2:6b:64:e0:b9:
                    cf:51:6e:58:5c:ca:3c:db:d4:3b:21:b6:42:40:76:
                    88:66:dd:bc:0f:9c:40:82:3f:20:b7:01:12:8e:c8:
                    df:31:ad:ea:58:3a:5a:61:b2:7d:fe:2f:7b:69:8c:
                    e7:ef:ab:b4:d2:25:79:75:f7:88:23:91:44:46:ec:
                    08:73:d8:50:7f:a0:fa:b4:f9:df:58:2d:80:7f:4d:
                    30:a1:d8:7d:ab:fb:79:17:31:7f:81:c8:94:dc:20:
                    74:3e:d3:7f:ba:12:be:f7:f9:fd:2a:3a:66:32:cb:
                    f5:3a:d6:59:a3:60:64:13:ce:58:4b:c7:30:56:67:
                    5c:6f:2c:d2:4a:68:c1:a8:64:78:03:c8:9d:79:6c:
                    bc:82:72:e4:a9:d0:66:05:9c:18:6d:c2:f4:b7:04:
                    be:b0:be:e8:68:9f:93:41:4e:32:dd:9c:f4:73:60:
                    0f:2c:6c:fa:b4:49:5a:69:51:0c:9d:69:56:37:bd:
                    d0:46:dc:7b:28:5a:ad:9d:f6:14:2c:e9:ce:7a:53:
                    2b:29:6b:1a:6c:90:a8:e9:11:da:52:a7:ff:ff:8d:
                    f4:36:70:70:2e:a7:80:1e:40:14:1a:8a:77:be:11:
                    fc:c5
                Exponent: 65537 (0x10001)
        X509v3 extensions:
            X509v3 Key Usage: critical
                Certificate Sign, CRL Sign
            X509v3 Basic Constraints: critical
                CA:TRUE
            X509v3 Subject Key Identifier:
                57:CC:17:CF:CF:21:94:71:42:B8:AB:06:7C:FD:FC:45:6D:F9:6A:4F
            X509v3 Authority Key Identifier:
                keyid:DB:3A:73:7A:03:25:2E:17:48:46:58:67:19:AD:86:2E:04:3D:EB:EC

    Signature Algorithm: sha256WithRSAEncryption
         88:e6:3d:6f:b3:11:a6:6f:6c:e1:77:5a:7b:ac:b2:62:6e:7b:
         69:24:7c:53:83:4a:86:f6:90:ca:cc:ed:de:ad:40:e2:6b:9d:
         e2:7d:34:5c:85:18:cd:aa:07:1d:4c:93:bc:f4:c6:c2:56:93:
         1c:2b:cf:3e:13:4d:57:dc:ab:46:64:c1:51:dd:5e:08:d4:69:
         a9:b5:d8:38:96:e8:9c:63:3a:ce:f7:64:b8:d0:28:91:1e:bf:
         54:17:3f:02:7e:d8:3d:27:11:99:02:4d:0c:37:74:9c:a6:3b:
         71:3c:cd:5f:66:ce:1d:d8:83:6d:42:dc:a3:b5:9f:c8:f3:a8:
         ad:a2:03:ec:28:7a:3b:86:b2:1d:a3:d2:06:98:56:bb:38:7b:
         ae:97:fb:98:97:76:7d:70:d2:ce:00:41:dc:04:56:ab:43:d5:
         67:bd:09:8f:a5:d6:aa:de:de:00:af:01:47:46:b9:f9:64:c8:
         0c:f4:76:ef:45:b8:2b:de:7b:39:53:8b:97:f5:37:52:79:f1:
         da:b2:1a:00:b9:51:af:20:5a:ae:32:95:63:d1:a8:d4:01:e7:
         75:ca:e5:5d:ed:2d:94:48:4d:6c:f1:1c:8d:ee:3d:ed:d0:3e:
         c5:1b:ba:51:10:24:c1:9d:96:0a:a8:17:3b:38:8d:98:76:2c:
         1d:3e:f4:07


Валидация с помошью корневого CA

openssl verify -verbose -CAfile rootCA.pem intermediateCA.cert.pem
intermediateCA.cert.pem: OK


Конфигурация Vault для использования промежуточного CA

Загрузка промежуточного сертефиката

vault write pki_intermediate_ca/intermediate/set-signed \
    certificate=@intermediateCA.cert.pem

Configure URLs

vault write pki_intermediate_ca/config/urls \
    issuing_certificates="http://vault.home:8200/v1/pki_intermediate_ca/ca" \
    crl_distribution_points="http://vault.home:8200/v1/pki_intermediate_ca/crl"

Работа с PKI

Создание пользователей и ролей не относится непосредсвенно к настройке PKI но доьбавлено для полноты так как все равно надо настроить =)

Роли

По сути роли здесь - это Путь к которому нужно будет дать доступ с помошью политик

Тестовая роль для серверных сертификатов

  • example-dot-home-server-server-crt - имя роли
vault write pki_intermediate_ca/roles/example-dot-home-server-crt \
    country="Ukraine" \
    locality="Kharkov" \
    street_address="Lui Pastera st 322 app. 311"\
    postal_code="61172" \
    organization="Home Network" \
    ou="IT" \
    allowed_domains="example.home" \
    allow_subdomains=true \
    max_ttl="87600h" \
    key_bits="2048" \
    key_type="rsa" \
    allow_any_name=false \
    allow_bare_domains=false \
    allow_glob_domain=false \
    allow_ip_sans=true \
    allow_localhost=false \
    client_flag=false \
    server_flag=true \
    enforce_hostnames=true \
    key_usage="DigitalSignature,KeyEncipherment" \
    ext_key_usage="ServerAuth" \
    require_cn=true

Тестовая роль для клиентских сертификатов

vault write pki_intermediate_ca/roles/example-dot-home-client-crt \
    country="Ukraine" \
    locality="Kharkov" \
    street_address="Lui Pastera st. 322 app. 131" \
    postal_code="61172" \
    organization="Home Network" \
    ou="IT" \
    allow_subdomains=true \
    max_ttl="87600h" \
    key_bits="2048" \
    key_type="rsa" \
    allow_any_name=true \
    allow_bare_domains=false \
    allow_glob_domain=false \
    allow_ip_sans=false \
    allow_localhost=false \
    client_flag=true \
    server_flag=false \
    enforce_hostnames=false \
    key_usage="DigitalSignature" \
    ext_key_usage="ClientAuth" \
    require_cn=true


Просмотр ролей

vault list  pki_intermediate_ca/roles
Keys
----
example-dot-home-client-crt
example-dot-home-server-crt
vault read  pki_intermediate_ca/roles/example-dot-home-server-crt
Key                                   Value
---                                   -----
allow_any_name                        false
allow_bare_domains                    false
allow_glob_domains                    false
allow_ip_sans                         true
allow_localhost                       false
allow_subdomains                      true
allow_token_displayname               false
allowed_domains                       [example.home]
allowed_domains_template              false
allowed_other_sans                    []
allowed_serial_numbers                []
allowed_uri_sans                      []
basic_constraints_valid_for_non_ca    false
client_flag                           false
code_signing_flag                     false
country                               [Ukraine]
email_protection_flag                 false
enforce_hostnames                     true
ext_key_usage                         [ServerAuth]
ext_key_usage_oids                    []
generate_lease                        false
key_bits                              2048
key_type                              rsa
key_usage                             [DigitalSignature KeyEncipherment]
locality                              [Kharkov]
max_ttl                               87600h
no_store                              false
not_before_duration                   30s
organization                          [Home Network]
ou                                    [IT]
policy_identifiers                    []
postal_code                           [61172]
province                              []
require_cn                            true
server_flag                           true
street_address                        [Lui Pastera st 322 app. 311]
ttl                                   0s
use_csr_common_name                   true
use_csr_sans                          true


Политики

  • По сути политики определяют права доступа ТОКЕНА к определнному пути. Токен же выдается при логине - т е в простейшем случае политики должны назначаться на пользователя (авторизация по логину/паролю)

Для доступа к ролям создаем 2 файла с политиками:

Политика для серверных сертефикатов

example-dot-home-server-crt-policy.hlc
path "pki_intermediate_ca/issue/example-dot-home-server-crt"
{
  capabilities = ["read", "create", "list", "update"]
}

Политика для клиентских сертефикатов

example-dot-home-client-crt-policy.hlc
path "pki_intermediate_ca/issue/example-dot-home-client-crt"
{
  capabilities = ["read", "create", "list", "update"]
}

Создание политик из файлов

vault policy write example-dot-home-server-crt-policy  example-dot-home-server-crt-policy.hlc
vault policy write example-dot-home-client-crt-policy  example-dot-home-client-crt-policy.hlc

Проверка созданных политик

vault policy list
default
example-dot-home-client-crt-policy
example-dot-home-server-crt-policy
root
vault policy read example-dot-home-server-crt-policy
path "pki_intermediate_ca/issue/example-dot-home-server-crt"
{
  capabilities = ["read", "create", "list", "update"]
}
vault policy read example-dot-home-client-crt-policy
path "pki_intermediate_ca/issue/example-dot-home-client-crt"
{
  capabilities = ["read", "create", "list", "update"]
}

Привязка политик к пользователям

  • Пользователи с логином и паролем хорошо подходят для тестирования - в реальных окружениях будет использоваться что-то дроугое, сервисные аккаунты или еще что-то.
  • Включить авторизацию по логину/паролю нужно заранее (https://noname.com.ua/mediawiki/index.php/Vault)

Просмотр пользователей

vault list  auth/userpass/users

Создание пользователей

  • Политики перечисляются через запятую (что не очевидно)
  • Имена пользователей "говорят" о их назначении
  • Пароли простые для тестирования но разные у разных пользователей (для того что бы не допустить ошибок при тестировании и не перепутать пользователя)

Пользователь для получения серверных сертификатов

vault \
  write auth/userpass/users/example-dot-home-server-crt-user \
  password=server \
  policies="example-dot-home-server-crt-policy,default"

Пользователь для получения клиентских сертификатов

vault \
  write auth/userpass/users/example-dot-home-client-crt-user \
  password=client \
  policies="example-dot-home-client-crt-policy,default"

Пользователь для получения и серверных и клиентских сертификатов

vault \
  write auth/userpass/users/example-dot-home-any-crt-user \
  password=any \
  policies="example-dot-home-server-crt-policy,example-dot-home-client-crt-policy,default"

Просмотр созданных пользователей

vault list  auth/userpass/users
Keys
----
example-dot-home-any-crt-user
example-dot-home-client-crt-user
example-dot-home-server-crt-user
vault read  auth/userpass/users/example-dot-home-any-crt-user
Key                        Value
---                        -----
policies                   [default example-dot-home-client-crt-policy example-dot-home-server-crt-policy]
token_bound_cidrs          []
token_explicit_max_ttl     0s
token_max_ttl              0s
token_no_default_policy    false
token_num_uses             0
token_period               0s
token_policies             [default example-dot-home-client-crt-policy example-dot-home-server-crt-policy]
token_ttl                  0s
token_type                 default
vault read  auth/userpass/users/example-dot-home-server-crt-user
Key                        Value
---                        -----
policies                   [default example-dot-home-server-crt-policy]
token_bound_cidrs          []
token_explicit_max_ttl     0s
token_max_ttl              0s
token_no_default_policy    false
token_num_uses             0
token_period               0s
token_policies             [default example-dot-home-server-crt-policy]
token_ttl                  0s
token_type                 default
vault read  auth/userpass/users/example-dot-home-client-crt-user
Key                        Value
---                        -----
policies                   [default example-dot-home-client-crt-policy]
token_bound_cidrs          []
token_explicit_max_ttl     0s
token_max_ttl              0s
token_no_default_policy    false
token_num_uses             0
token_period               0s
token_policies             [default example-dot-home-client-crt-policy]
token_ttl                  0s
token_type                 default

Проверка получения сертефикатов

Получение серверного сертефиката

Авторизация с логином и паролем

vault \
    login \
    -method=userpass \
    username=example-dot-home-server-crt-user \
    password=server
Key                    Value
---                    -----
token                  s.Wiy7YVCrte88i0QIHc4jmvQP
token_accessor         ptB7o9d6yOq5w4Ra5Q44W1FF
token_duration         768h
token_renewable        true
token_policies         ["default" "example-dot-home-server-crt-policy"]
identity_policies      []
policies               ["default" "example-dot-home-server-crt-policy"]
token_meta_username    example-dot-home-server-crt-user

Получение сертефиката

vault write -format=json pki_intermediate_ca/issue/example-dot-home-server-crt \
    common_name="vault.example.home" \
    alt_names="pki.example.home" \
    ttl="43800h" > vault.example.home.crt


Проверка полученного сертефиката

cat vault.example.home.crt
{
  "request_id": "3d679cb8-0aa1-9920-672e-b56831fc53b8",
  "lease_id": "",
  "lease_duration": 0,
  "renewable": false,
  "data": {
    "ca_chain": [
      "-----BEGIN CERTIFICATE-----uVGvIFquMpVj\n0ajUAed1yuVd7S2USE1s8RyN7j3t0D7FG7pRECTBnZYKqBc7OI2YdiwdPvQH\n-----END CERTIFICATE-----"
    ],
    "certificate": "-----BEGIN CERTIFICATE-----dNVFGyG16ZABF66E1j1O/MTRjB3cZIHj1rMP\nc84dH3ykPoe80T6zGblRgxrZOIh/EQ==\n-----END CERTIFICATE-----",
    "expiration": 1791633878,
    "issuing_ca": "-----BEGIN CERTIFICATE-----uVGvIFquMpVj\n0ajUAed1yuVd7S2USE1s8RyN7j3t0D7FG7pRECTBnZYKqBc7OI2YdiwdPvQH\n-----END CERTIFICATE-----",
    "private_key": "-----BEGIN RSA PRIVATE KEY-----aAg7YWcEsZMl\ntdqBAoGAX5UJPX9VSbm/kI5nruAnQXcfkmUWIQA3GDWdbGfqaY4AZZleQv/0mMJf\nAgUT+e/vFuHaDAxY6rXh7dl3aM3JiJgdLxJ1vFFeaKqHHonH83PT0921S+MLiB5/\n9EdomgHndqzJXVrMLThUR6PiUTZtrG48tsI6w9rOk1ZELvE5HJI=\n-----END RSA PRIVATE KEY-----",
    "private_key_type": "rsa",
    "serial_number": "3b:a5:4d:03:64:bf:91:b5:6a:6f:0a:c8:aa:05:11:68:29:a8:6d:dd"
  },
  "warnings": null
}
cat vault.example.home.crt | jq -r .data.ca_chain[] > ca_chain.pem
cat vault.example.home.crt | jq -r .data.certificate > certificate.pem
cat vault.example.home.crt | jq -r .data.issuing_ca > issuing_ca.pem
Сертификат сервера

Наиболее интересные поля - ожидаемые значения:

  • CN = vault.example.home
  • X509v3 Subject Alternative Name: DNS:pki.example.home, DNS:vault.example.home
openssl  x509 -in certificate.pem -text -noout
Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number:
            3b:a5:4d:03:64:bf:91:b5:6a:6f:0a:c8:aa:05:11:68:29:a8:6d:dd
        Signature Algorithm: sha256WithRSAEncryption
        Issuer: C = Ukraine, L = Kharkov, street = Lui Pastera st. 322 app. 131, postalCode = 61172, O = Home Network, OU = IT, CN = Intermediate CA
        Validity
            Not Before: Oct 11 12:04:12 2021 GMT
            Not After : Oct 10 12:04:38 2026 GMT
        Subject: C = Ukraine, L = Kharkov, street = Lui Pastera st 322 app. 311, postalCode = 61172, O = Home Network, OU = IT, CN = vault.example.home
        Subject Public Key Info:
            Public Key Algorithm: rsaEncryption
                RSA Public-Key: (2048 bit)
                Modulus:
                Exponent: 65537 (0x10001)
        X509v3 extensions:
            X509v3 Key Usage: critical
                Digital Signature, Key Encipherment
            X509v3 Extended Key Usage:
                TLS Web Server Authentication
            X509v3 Subject Key Identifier:
                5B:00:DB:44:EB:59:B4:9A:86:BE:9D:3D:A3:E0:DC:C6:EC:71:E4:BB
            X509v3 Authority Key Identifier:
                keyid:57:CC:17:CF:CF:21:94:71:42:B8:AB:06:7C:FD:FC:45:6D:F9:6A:4F

            Authority Information Access:
                CA Issuers - URI:http://vault.home:8200/v1/pki_intermediate_ca/ca

            X509v3 Subject Alternative Name:
                DNS:pki.example.home, DNS:vault.example.home
            X509v3 CRL Distribution Points:

                Full Name:
                  URI:http://vault.home:8200/v1/pki_intermediate_ca/crl

    Signature Algorithm: sha256WithRSAEncryption
Промежуточный CA
openssl  x509 -in issuing_ca.pem -text -noout
Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number:
            40:b2:aa:32:ee:ea:2f:84:75:bb:8f:ec:2e:98:56:70:1c:66:f6:0d
        Signature Algorithm: sha256WithRSAEncryption
        Issuer: C = Ukraine, L = Kharkov, street = app. 131 + street = Lui Pastera St. 322, postalCode = 61172, O = Home Network, OU = IT, CN = Root Certificate Authority for Home Network
        Validity
            Not Before: Oct 11 09:22:37 2021 GMT
            Not After : Oct  6 09:23:07 2041 GMT
        Subject: C = Ukraine, L = Kharkov, street = Lui Pastera st. 322 app. 131, postalCode = 61172, O = Home Network, OU = IT, CN = Intermediate CA
        Subject Public Key Info:
            Public Key Algorithm: rsaEncryption
                RSA Public-Key: (2048 bit)
                Modulus:
                Exponent: 65537 (0x10001)
        X509v3 extensions:
            X509v3 Key Usage: critical
                Certificate Sign, CRL Sign
            X509v3 Basic Constraints: critical
                CA:TRUE
            X509v3 Subject Key Identifier:
                57:CC:17:CF:CF:21:94:71:42:B8:AB:06:7C:FD:FC:45:6D:F9:6A:4F
            X509v3 Authority Key Identifier:
                keyid:DB:3A:73:7A:03:25:2E:17:48:46:58:67:19:AD:86:2E:04:3D:EB:EC

    Signature Algorithm: sha256WithRSAEncryption
Верефикация
  • Указать промежуточный как untrusted (или добавить rootCA в доверенные)
openssl verify -verbose -CAfile rootCA.pem -untrusted issuing_ca.pem certificate.pem
certificate.pem: OK

Получение клиентского сертефиката

Проверка прав

С "серверным" пользователем - нет прав

URL: PUT http://vault.home:8200/v1/pki_intermediate_ca/issue/example-dot-home-client-crt
Code: 403. Errors:

* 1 error occurred:
	* permission denied

Получение клиентского сертификата c правильным пользователем

vault \
    login \
    -method=userpass \
    username=example-dot-home-client-crt-user \
    password=client

vault write -format=json pki_intermediate_ca/issue/example-dot-home-client-crt \
    common_name="vault.example.home" \
    alt_names="pki.example.home" \
    ttl="43800h" > vault.example.home.CLIENT.json

Ожидаемый результат:

X509v3 Extended Key Usage:
  TLS Web Client Authentication
openssl x509 -noout -text -in certificate_client.pem
Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number:
            29:02:a3:28:8e:fc:48:bd:1a:5b:f9:46:e1:bf:87:27:e0:80:79:c3
        Signature Algorithm: sha256WithRSAEncryption
        Issuer: C = Ukraine, L = Kharkov, street = Lui Pastera st. 322 app. 131, postalCode = 61172, O = Home Network, OU = IT, CN = Intermediate CA
        Validity
            Not Before: Oct 11 12:31:10 2021 GMT
            Not After : Oct 10 12:31:37 2026 GMT
        Subject: C = Ukraine, L = Kharkov, street = Lui Pastera st. 322 app. 131, postalCode = 61172, O = Home Network, OU = IT, CN = vault.example.home
        Subject Public Key Info:
            Public Key Algorithm: rsaEncryption
                RSA Public-Key: (2048 bit)
                Modulus:
           Exponent: 65537 (0x10001)
        X509v3 extensions:
            X509v3 Key Usage: critical
                Digital Signature
            X509v3 Extended Key Usage:
                TLS Web Client Authentication
            X509v3 Subject Key Identifier:
                4A:1E:33:0C:03:E0:91:6D:17:1E:2B:4A:9F:53:98:7D:4C:80:43:83

Проверка прав для пользователя any

  • работает каки ожидалось - можно получить сертификаты как для сервера так и для клиента
vault \
    login \
    -method=userpass \
    username=example-dot-home-any-crt-user \
    password=any


vault write -format=json pki_intermediate_ca/issue/example-dot-home-client-crt \
    common_name="vault.example.home" \
    alt_names="pki.example.home" \
    ttl="43800h" > vault.example.home.CLIENT_by_any_user.json


vault write -format=json pki_intermediate_ca/issue/example-dot-home-server-crt \
    common_name="vault.example.home" \
    alt_names="pki.example.home" \
    ttl="43800h" > vault.example.home.SERVER_by_any_user.json

Работа с PKI

Посмотреть список сертификатов

vault list pki_intermediate_ca/certs
Keys
----
0e-be-9c-c3-80-0c-e2-51-e0-f8-e3-00-0d-5a-42-d3-cd-13-54-be
10-3c-b0-8c-50-8c-4f-21-14-a6-fd-32-36-87-ce-85-ef-e9-23-d2
29-02-a3-28-8e-fc-48-bd-1a-5b-f9-46-e1-bf-87-27-e0-80-79-c3
29-6a-69-20-c3-c2-a8-f3-ae-e7-13-0c-6b-52-c5-b6-49-c4-a3-77
38-b4-31-fc-82-6a-39-26-08-29-24-2d-da-ed-63-95-5c-7d-77-2b
3b-a5-4d-03-64-bf-91-b5-6a-6f-0a-c8-aa-05-11-68-29-a8-6d-dd
40-b2-aa-32-ee-ea-2f-84-75-bb-8f-ec-2e-98-56-70-1c-66-f6-0d

Прочитать сертификат

  • 40-b2-aa-32-ee-ea-2f-84-75-bb-8f-ec-2e-98-56-70-1c-66-f6-0d это serial сертификата
vault read pki_intermediate_ca/cert/40-b2-aa-32-ee-ea-2f-84-75-bb-8f-ec-2e-98-56-70-1c-66-f6-0d --format=json
{
  "request_id": "a7af8390-c94b-6055-2148-283746cd64fa",
  "lease_id": "",
  "lease_duration": 0,
  "renewable": false,
  "data": {
    "certificate": "-----BEGIN CERTIFICATE-----\nMIIESTCCAzGgAwIBAgIUQLKqMu7qL4R1u4/sLphWcBxm9g0wDQYJKoZIhvcNAQEL\nBQAwgb0xEDAOBgNVBAYTB1VrcmFpbmUxEDAOBgNVBAcTB0toYXJrb3YxLTAPBgNV\nBAkTCGFwcC4gMTMxMBoGA1UECRMTTHVpIFBhc3RlcmEgU3QuIDMyMjEOMAwGA1UE\nERMFNjExNzIxFTATBgNVBAoTDEhvbWUgTmV0d29yazELMAkGA1UECxMCSVQxNDAy\nBgNVBAMTK1Jvb3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5IGZvciBIb21lIE5ldHdv\ncmswHhcNMjExMDExMDkyMjM3WhcNNDExMDA2MDkyMzA3WjCBmTEQMA4GA1UEBhMH\nVWtyYWluZTEQMA4GA1UEBxMHS2hhcmtvdjElMCMGA1UECRMcTHVpIFBhc3RlcmEg\nc3QuIDMyMiBhcHAuIDEzMTEOMAwGA1UEERMFNjExNzIxFTATBgNVBAoTDEhvbWUg\nTmV0d29yazELMAkGA1UECxMCSVQxGDAWBgNVBAMTD0ludGVybWVkaWF0ZSBDQTCC\nASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMgmWZZFkFcuAzKZa2VQKf37\ncjUFLVb4rLJrZOC5z1FuWFzKPNvUOyG2QkB2iGbdvA+cQII/ILcBEo7I3zGt6lg6\nWmGyff4ve2mM5++rtNIleXX3iCORREbsCHPYUH+g+rT531gtgH9NMKHYfav7eRcx\nf4HIlNwgdD7Tf7oSvvf5/So6ZjLL9TrWWaNgZBPOWEvHMFZnXG8s0kpowahkeAPI\nnXlsvIJy5KnQZgWcGG3C9LcEvrC+6Gifk0FOMt2c9HNgDyxs+rRJWmlRDJ1pVje9\n0EbceyharZ32FCzpznpTKylrGmyQqOkR2lKn//+N9DZwcC6ngB5AFBqKd74R/MUC\nAwEAAaNjMGEwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0O\nBBYEFFfMF8/PIZRxQrirBnz9/EVt+WpPMB8GA1UdIwQYMBaAFNs6c3oDJS4XSEZY\nZxmthi4EPevsMA0GCSqGSIb3DQEBCwUAA4IBAQCI5j1vsxGmb2zhd1p7rLJibntp\nJHxTg0qG9pDKzO3erUDia53ifTRchRjNqgcdTJO89MbCVpMcK88+E01X3KtGZMFR\n3V4I1Gmptdg4luicYzrO92S40CiRHr9UFz8Cftg9JxGZAk0MN3ScpjtxPM1fZs4d\n2INtQtyjtZ/I86itogPsKHo7hrIdo9IGmFa7OHuul/uYl3Z9cNLOAEHcBFarQ9Vn\nvQmPpdaq3t4ArwFHRrn5ZMgM9HbvRbgr3ns5U4uX9TdSefHashoAuVGvIFquMpVj\n0ajUAed1yuVd7S2USE1s8RyN7j3t0D7FG7pRECTBnZYKqBc7OI2YdiwdPvQH\n-----END CERTIFICATE-----",
    "revocation_time": 0
  },
  "warnings": null
}

Отозвать сертификат

vault write pki_intermediate_ca/revoke serial_number=
<serial number>

Очистить просроченные / отозванные сертификаты

vault write pki_intermediate_ca/tidy \
    safety_buffer=5s \
    tidy_cert_store=true \
    tidy_revocation_list=true

Проверка сертификатов с Nginx

Для проверки работы сертификатов настроим nginx как proxy. в качестве бекенда выступает сам Vault

Настройка Nginx

Предварительный конфиг виртуалхоста (пока не загружаю - так как ни ключа ни сертификата пока нет)

server {
    listen 8202 default_server ssl;
    root /var/www/html;
    server_name vault.home vault.local;
    access_log /var/log/nginx/vault-access.log postdata;
    error_log /var/log/nginx/vault-error.log;

    ssl_certificate     /etc/nginx/certs/vault.crt;
    ssl_certificate_key /etc/nginx/certs/vault.key;
    ssl_protocols       TLSv1 TLSv1.1 TLSv1.2;
    ssl_ciphers         HIGH:!aNULL:!MD5;

    location / {
        client_body_buffer_size      64k;
        client_body_in_single_buffer on;
        proxy_pass                   http://127.0.0.1:8200;
        proxy_set_header             Host $host:$server_port;
        proxy_set_header             X-Real-IP $remote_addr;
        proxy_set_header             X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header             X-Forwarded-Proto $scheme;
        proxy_http_version           1.1;
        proxy_request_buffering      off;
    }
}

Настройка Vault

Создание роли

Роль ждя сертификата для домена vault.home

vault write pki_intermediate_ca/roles/vault-dot-home-server-crt \
    country="Ukraine" \
    locality="Kharkov" \
    street_address="Lui Pastera st 322 app. 311"\
    postal_code="61172" \
    organization="Home Network" \
    ou="IT" \
    allowed_domains="vault.home" \
    allow_subdomains=false \
    max_ttl="87600h" \
    key_bits="2048" \
    key_type="rsa" \
    allow_any_name=false \
    allow_bare_domains=true \
    allow_glob_domain=false \
    allow_ip_sans=true \
    allow_localhost=false \
    client_flag=false \
    server_flag=true \
    enforce_hostnames=true \
    key_usage="DigitalSignature,KeyEncipherment" \
    ext_key_usage="ServerAuth" \
    require_cn=true

Создание политик

  • Файл vault-dot-home-server-crt-policy.hlc
path "pki_intermediate_ca/issue/vault-dot-home-server-crt"
{
  capabilities = ["read", "create", "list", "update"]
}
vault \
    policy \
        write \
            vault-dot-home-server-crt-policy \
            vault-dot-home-server-crt-policy.hlc

Создание пользователя для работы с сертефикатами

Еще раз подчеркну что пользователи используются тут ТОЛЬКО В ТЕСТОВЫХ ЦЕЛЯХ.

Существующие пользователи

vault list  auth/userpass/users
Keys
----
example-dot-home-any-crt-user
example-dot-home-client-crt-user
example-dot-home-server-crt-user

Новый пользователь с политикой для домена vault.home

  • username: vault-dot-home-server-crt-user
  • password: vault
  • политики: vault-dot-home-server-crt-policy и default
vault \
  write auth/userpass/users/vault-dot-home-server-crt-user \
  password=vault \
  policies="vault-dot-home-server-crt-policy,default"

Проверка

export VAULT_ADDR="http://vault.home:8200"
unset VAULT_TOKEN


vault \
    login \
    -method=userpass \
    username=vault-dot-home-server-crt-user \
    password=vault


vault \
    write \
    -format=json pki_intermediate_ca/issue/vault-dot-home-server-crt \
    common_name="vault.home" \
    ttl="43800h" > vault.home.crt

Подготовка Consul Template

Установка

Так или иначе в зависимости от системы (это пример из интернета). Для arm версия другая.

$ wget https://releases.hashicorp.com/consul-template/0.19.5/consul-template_0.19.5_linux_amd64.zip
$ apt-get install unzip
$ unzip consul-template_0.19.5_linux_amd64.zip
$ mv consul-template /user/local/bin

Темплейты для сертефиката и ключа

  • /etc/consul-template.d/templates/vault-cert.tpl
{{- /* vault-cert.tpl */ -}}
{{ with secret "pki_intermediate_ca/issue/vault-dot-home-server-crt" "common_name=vault.home" "ttl=2m" }}
{{ .Data.certificate }}
{{ .Data.issuing_ca }}{{ end }}


  • /etc/consul-template.d/templates/vault-key.tpl
{{- /* vault-dot-home-key.tpl */ -}}
{{ with secret "pki_intermediate_ca/issue/vault-dot-home-server-crt" "common_name=vault.home" "ttl=2m"}}
{{ .Data.private_key }}{{ end }}

Конфигурация consul-template

  • /etc/consul-template.d/configs/nginx-vault.hcl

token пропущен так как авторизация через логин/пароль и токен получается динамически

vault {
  address = "http://vault.home:8200"
#  token = "<TOKEN_HERE>"
  renew_token = true

  retry {
    enabled = true
    attempts = 5
    backoff = "250ms"
  }
}

template {
  source      = "/etc/consul-template.d/templates/vault-cert.tpl"
  destination = "/etc/nginx/certs/vault.crt"
  perms       = "0600"
  command     = "systemctl reload nginx"
}

template {
  source      = "/etc/consul-template.d/templates/vault-key.tpl"
  destination = "/etc/nginx/certs/vault.key"
  perms       = "0600"
  command     = "systemctl reload nginx"
}

Тестовый запуск

Скрипт

#!/bin/bash

VAULT_TOKEN=$(vault \
    login \
    -method=userpass \
    username=vault-dot-home-server-crt-user \
    password=vault \
    --format=json | jq -r .auth.client_token
)


#echo ${VAULT_TOKEN}

export VAULT_TOKEN=${VAULT_TOKEN}

/usr/local/consul/bin/consul-template \
    -config /etc/consul-template.d/configs/nginx-vault.hcl

systemd unit

Создаю Unit-file:

  • имя файла /etc/systemd/system/consul-template-vault-nginx.service
  • Юнит "с дебагом"
  • Кроме всего прочего выводит переменные окружения (что бы убедиться что они нормально загружаются) и переменные systemd
  • Токен сохраняется во временном файле и потом отттуда попадает в переменные окружения
[Unit]
Description=consul-template for Nginx/Vault
Requires=network-online.target
After=network-online.target

[Service]
EnvironmentFile=-/etc/default/consul-template
EnvironmentFile=-/etc/default/%N
EnvironmentFile=-/tmp/vault-token-%N

Restart=on-failure
ExecStartPre=/usr/bin/env
ExecStartPre=/bin/bash -c " echo b=%b"
ExecStartPre=/bin/bash -c " echo g=%g"
ExecStartPre=/bin/bash -c " echo G=%G"
ExecStartPre=/bin/bash -c " echo H=%H"
ExecStartPre=/bin/bash -c " echo i=%i"
ExecStartPre=/bin/bash -c " echo j=%j"
ExecStartPre=/bin/bash -c " echo m=%m"
ExecStartPre=/bin/bash -c " echo n=%n"
ExecStartPre=/bin/bash -c " echo N=%N"
ExecStartPre=/bin/bash -c " echo p=%p"
ExecStartPre=/bin/bash -c " echo u=%u"
ExecStartPre=/bin/bash -c " echo U=%U"
ExecStartPre=/bin/bash -c " echo v=%v"
ExecStartPre=/bin/bash -c " echo %%"

ExecStartPre=/bin/bash -c "printf 'VAULT_TOKEN=' > /tmp/vault-token-%N; \
    /usr/local/vault/bin/vault \
        login \
        -method=userpass \
        username=$VAULT_USERNAME \
        password=$VAULT_PASSWORD \
        --format=json | jq -r .auth.client_token >> /tmp/vault-token-%N"

ExecStartPre=/usr/bin/env
ExecStart=/usr/local/consul/bin/consul-template \
    $OPTIONS \
    -config='/etc/consul-template.d/configs/nginx-vault.hcl'

KillSignal=SIGINT

[Install]
WantedBy=multi-user.target

Проверка работы

Безопастность игнорируется в тестом окружении - в проде нужно спрятать токены

systemctl  status consul-template-vault-nginx.service
● consul-template-vault-nginx.service - consul-template for Nginx/Vault
   Loaded: loaded (/etc/systemd/system/consul-template-vault-nginx.service; disabled; vendor preset: enabled)
   Active: active (running) since Fri 2021-10-15 14:07:37 EEST; 21min ago
  Process: 19036 ExecStartPre=/usr/bin/env (code=exited, status=0/SUCCESS)
  Process: 19037 ExecStartPre=/bin/bash -c  echo b=7d0758bee53b4ddbba5674ef66a7c067 (code=exited, status=0/SUCCESS)
  Process: 19038 ExecStartPre=/bin/bash -c  echo g=root (code=exited, status=0/SUCCESS)
  Process: 19039 ExecStartPre=/bin/bash -c  echo G=0 (code=exited, status=0/SUCCESS)
  Process: 19040 ExecStartPre=/bin/bash -c  echo H=raspberrypi4 (code=exited, status=0/SUCCESS)
  Process: 19041 ExecStartPre=/bin/bash -c  echo i= (code=exited, status=0/SUCCESS)
  Process: 19042 ExecStartPre=/bin/bash -c  echo j=nginx (code=exited, status=0/SUCCESS)
  Process: 19043 ExecStartPre=/bin/bash -c  echo m=f7cb830984574abd90d3b1a9616450f3 (code=exited, status=0/SUCCESS)
  Process: 19044 ExecStartPre=/bin/bash -c  echo n=consul-template-vault-nginx.service (code=exited, status=0/SUCCESS)
  Process: 19045 ExecStartPre=/bin/bash -c  echo N=consul-template-vault-nginx (code=exited, status=0/SUCCESS)
  Process: 19046 ExecStartPre=/bin/bash -c  echo p=consul-template-vault-nginx (code=exited, status=0/SUCCESS)
  Process: 19047 ExecStartPre=/bin/bash -c  echo u=root (code=exited, status=0/SUCCESS)
  Process: 19048 ExecStartPre=/bin/bash -c  echo U=0 (code=exited, status=0/SUCCESS)
  Process: 19049 ExecStartPre=/bin/bash -c  echo v=5.4.51-v7l+ (code=exited, status=0/SUCCESS)
  Process: 19050 ExecStartPre=/bin/bash -c  echo % (code=exited, status=0/SUCCESS)
  Process: 19051 ExecStartPre=/bin/bash -c printf 'VAULT_TOKEN=' > /tmp/vault-token-consul-template-vault-nginx (code=exited, status=0/SUCCESS)
  Process: 19052 ExecStartPre=/bin/bash -c printf 'VAULT_TOKEN=' > /tmp/vault-token-consul-template-vault-nginx;      /usr/local/vault/bin/vault          login          -method=userpass          username=$VAULT_USERNAME          password=$VAULT_PASSWORD          --format=json | jq -r .auth.
  Process: 19064 ExecStartPre=/usr/bin/env (code=exited, status=0/SUCCESS)
 Main PID: 19065 (consul-template)
    Tasks: 13 (limit: 4915)
   CGroup: /system.slice/consul-template-vault-nginx.service
           └─19065 /usr/local/consul/bin/consul-template -config=/etc/consul-template.d/configs/nginx-vault.hcl

Oct 15 14:07:37 raspberrypi4 env[19064]: LANGUAGE=en_US.UTF-8
Oct 15 14:07:37 raspberrypi4 env[19064]: LC_TIME=C.UTF-8
Oct 15 14:07:37 raspberrypi4 env[19064]: PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
Oct 15 14:07:37 raspberrypi4 env[19064]: INVOCATION_ID=01f3f30994c34ca6888059f640df7bce
Oct 15 14:07:37 raspberrypi4 env[19064]: JOURNAL_STREAM=8:79140900
Oct 15 14:07:37 raspberrypi4 env[19064]: VAULT_ADDR=http://127.0.0.1:8200
Oct 15 14:07:37 raspberrypi4 env[19064]: VAULT_USERNAME=vault-dot-home-server-crt-user
Oct 15 14:07:37 raspberrypi4 env[19064]: VAULT_PASSWORD=vault
Oct 15 14:07:37 raspberrypi4 env[19064]: VAULT_TOKEN=s.tByQQL0DBdUjQH2lXAu2wuS8
Oct 15 14:07:37 raspberrypi4 systemd[1]: Started consul-template for Nginx/Vault.

Проверка работы Nginx

Без корневого сертификата

Ожидаемо - не работает

curl https://vault.home:8202 -v
* Expire in 5 ms for 1 (transfer 0x1682880)
*   Trying 192.168.1.223...
* TCP_NODELAY set
* Expire in 200 ms for 4 (transfer 0x1682880)
* Connected to vault.home (192.168.1.223) port 8202 (#0)
* ALPN, offering h2
* ALPN, offering http/1.1
* successfully set certificate verify locations:
*   CAfile: none
  CApath: /etc/ssl/certs
* TLSv1.3 (OUT), TLS handshake, Client hello (1):
* TLSv1.3 (IN), TLS handshake, Server hello (2):
* TLSv1.2 (IN), TLS handshake, Certificate (11):
* TLSv1.2 (OUT), TLS alert, unknown CA (560):
* SSL certificate problem: unable to get local issuer certificate
* Closing connection 0
curl: (60) SSL certificate problem: unable to get local issuer certificate
More details here: https://curl.haxx.se/docs/sslcerts.html

curl failed to verify the legitimacy of the server and therefore could not
establish a secure connection to it. To learn more about this situation and
how to fix it, please visit the web page mentioned above.

Добавление корневого сертификата

  • Внимание - расширение файла ВАЖНО для утилиты update-ca-certificates. Если оставить PEM то сертификат не будет добавлен.
  • rootCA.pem - файл корневого сертификата (см выше по тексту)
  • Корневой сертификат (НО НЕ КЛЮЧ!) всегда можно получить curl http://vault.home:8200/v1/pki_root_ca/ca/pem
cp rootCA.pem /usr/local/share/ca-certificates/rootCA.crt
update-ca-certificates
Updating certificates in /etc/ssl/certs...
1 added, 0 removed; done.
Running hooks in /etc/ca-certificates/update.d...

Adding debian:rootCA.pem
done.
done.
root@raspberrypi4:/usr/local/share/ca-certificates/extra#

С добавленным корневым сертификатом

Ожидаемо работает: (404 это НЕ ошибка SSL)

curl https://vault.home:8202
404 page not found

Проверка обновления сертефикатов

while true;  do echo "" | openssl s_client -connect vault.home:8202  > 111 2>/dev/null ;  openssl x509 -in 111 -text -noout | grep -E 'Not [AB]'; sleep 30; done
            Not Before: Oct 15 11:55:07 2021 GMT
            Not After : Oct 15 11:57:35 2021 GMT
            Not Before: Oct 15 11:55:07 2021 GMT
            Not After : Oct 15 11:57:35 2021 GMT
            Not Before: Oct 15 11:55:07 2021 GMT
            Not After : Oct 15 11:57:35 2021 GMT
            Not Before: Oct 15 11:56:11 2021 GMT

Проверка отзыва сертификатов

TBD!

Дополнения

Параметры сертификатов

  • name (string: <required>) – Specifies the name of the role to create. This is part of the request URL.
  • ttl (string: "") – Specifies the Time To Live value provided as a string duration with time suffix. Hour is the largest suffix. If not set, uses the system default value or the value of max_ttl, whichever is shorter.
  • max_ttl (string: "") – Specifies the maximum Time To Live provided as a string duration with time suffix. Hour is the largest suffix. If not set, defaults to the system maximum lease TTL.
  • allow_localhost (bool: true) – Specifies if clients can request certificates for localhost as one of the requested common names. This is useful for testing and to allow clients on a single host to talk securely.
  • allowed_domains (list: []) – Specifies the domains of the role. This is used with the allow_bare_domains and allow_subdomains options.
  • allowed_domains_template ()bool: false) – When set, allowed_domains may contain templates, as with ACL Path Templating.
  • allow_bare_domains (bool: false) – Specifies if clients can request certificates matching the value of the actual domains themselves; e.g. if a configured domain set with allowed_domains is example.com, this allows clients to actually request a certificate containing the name example.com as one of the DNS values on the final certificate. In some scenarios, this can be considered a security risk.
  • allow_subdomains (bool: false) – Specifies if clients can request certificates with CNs that are subdomains of the CNs allowed by the other role options. This includes wildcard subdomains. For example, an allowed_domains value of example.com with this option set to true will allow foo.example.com and bar.example.com as well as *.example.com. This is redundant when using the allow_any_name option.
  • allow_glob_domains (bool: false) - Allows names specified in allowed_domains to contain glob patterns (e.g. ftp*.example.com). Clients will be allowed to request certificates with names matching the glob patterns.
  • allow_any_name (bool: false) – Specifies if clients can request any CN. Useful in some circumstances, but make sure you understand whether it is appropriate for your installation before enabling it.
  • enforce_hostnames (bool: true) – Specifies if only valid host names are allowed for CNs, DNS SANs, and the host part of email addresses.
  • allow_ip_sans (bool: true) – Specifies if clients can request IP Subject Alternative Names. No authorization checking is performed except to verify that the given values are valid IP addresses.
  • allowed_uri_sans (string: "") - Defines allowed URI Subject Alternative Names. No authorization checking is performed except to verify that the given values are valid URIs. This can be a comma-delimited list or a JSON string slice. Values can contain glob patterns (e.g. spiffe://hostname/*).
  • allowed_other_sans (string: "") – Defines allowed custom OID/UTF8-string SANs. This can be a comma-delimited list or a JSON string slice, where each element has the same format as OpenSSL: <oid>;<type>:<value>, but the only valid type is UTF8 or UTF-8. The value part of an element may be a * to allow any value with that OID. Alternatively, specifying a single * will allow any other_sans input.
  • server_flag (bool: true) – Specifies if certificates are flagged for server use.
  • client_flag (bool: true) – Specifies if certificates are flagged for client use.
  • code_signing_flag (bool: false) – Specifies if certificates are flagged for code signing use.
  • email_protection_flag (bool: false) – Specifies if certificates are flagged for email protection use.
  • key_type (string: "rsa") – Specifies the type of key to generate for generated private keys and the type of key expected for submitted CSRs. Currently, rsa and ec are supported, or when signing CSRs any can be specified to allow keys of either type and with any bit size (subject to > 1024 bits for RSA keys).
  • key_bits (int: 2048) – Specifies the number of bits to use for the generated keys. This will need to be changed for ec keys, e.g., 224, 256, 384 or 521.
  • key_usage (list: ["DigitalSignature", "KeyAgreement", "KeyEncipherment"]) – Specifies the allowed key usage constraint on issued certificates. Valid values can be found at https://golang.org/pkg/crypto/x509/#KeyUsage - simply drop the KeyUsage part of the value. Values are not case-sensitive. To specify no key usage constraints, set this to an empty list.
  • ext_key_usage (list: []) – Specifies the allowed extended key usage constraint on issued certificates. Valid values can be found at https://golang.org/pkg/crypto/x509/#ExtKeyUsage - simply drop the ExtKeyUsage part of the value. Values are not case-sensitive. To specify no key usage constraints, set this to an empty list.
  • ext_key_usage_oids (string: "") - A comma-separated string or list of extended key usage oids.
  • use_csr_common_name (bool: true) – When used with the CSR signing endpoint, the common name in the CSR will be used instead of taken from the JSON data. This does not include any requested SANs in the CSR; use use_csr_sans for that.
  • use_csr_sans (bool: true) – When used with the CSR signing endpoint, the subject alternate names in the CSR will be used instead of taken from the JSON data. This does not include the common name in the CSR; use use_csr_common_name for that.
  • ou (string: "") – Specifies the OU (OrganizationalUnit) values in the subject field of issued certificates. This is a comma-separated string or JSON array.
  • organization (string: "") – Specifies the O (Organization) values in the subject field of issued certificates. This is a comma-separated string or JSON array.
  • country (string: "") – Specifies the C (Country) values in the subject field of issued certificates. This is a comma-separated string or JSON array.
  • locality (string: "") – Specifies the L (Locality) values in the subject field of issued certificates. This is a comma-separated string or JSON array.
  • province (string: "") – Specifies the ST (Province) values in the subject field of issued certificates. This is a comma-separated string or JSON array.
  • street_address (string: "") – Specifies the Street Address values in the subject field of issued certificates. This is a comma-separated string or JSON array.
  • postal_code (string: "") – Specifies the Postal Code values in the subject field of issued certificates. This is a comma-separated string or JSON array.
  • serial_number (string: "") – Specifies the Serial Number, if any. Otherwise Vault will generate a random serial for you. If you want more than one, specify alternative names in the alt_names map using OID 2.5.4.5.
  • generate_lease (bool: false) – Specifies if certificates issued/signed against this role will have Vault leases attached to them. Certificates can be added to the CRL by vault revoke <lease_id> when certificates are associated with leases. It can also be done using the pki/revoke endpoint. However, when lease generation is disabled, invoking pki/revoke would be the only way to add the certificates to the CRL.
  • no_store (bool: false) – If set, certificates issued/signed against this role will not be stored in the storage backend. This can improve performance when issuing large numbers of certificates. However, certificates issued in this way cannot be enumerated or revoked, so this option is recommended only for certificates that are non-sensitive, or extremely short-lived. This option implies a value of false for generate_lease.
  • require_cn (bool: true) - If set to false, makes the common_name field optional while generating a certificate.
  • policy_identifiers (list: []) – A comma-separated string or list of policy OIDs.
  • basic_constraints_valid_for_non_ca (bool: false) - Mark Basic Constraints valid when issuing non-CA certificates.
  • not_before_duration (duration: "30s") – Specifies the duration by which to backdate the NotBefore property.

Ссылки

Русскоязычные

Vault

Прочие