Vault PKI Kubernetes the hard way v2: различия между версиями

Материал из noname.com.ua
Перейти к навигацииПерейти к поиску
(Новая страница: «Категория:K8s Категория:Hashicorp_Vault Категория:Vault Категория:Linux Категория:Kubernetes the ha...»)
 
 
(не показано 38 промежуточных версий этого же участника)
Строка 5: Строка 5:
 
[[Категория:Kubernetes the hard way v2]]
 
[[Категория:Kubernetes the hard way v2]]
   
=Vault PKI=
+
=Vault PKI for k8s=
  +
Эта статья основана на [[Vault_PKI]] и во многом дублирует ее, но тут я постарался подробно описать все применительно к "самодельному" домашнему кластеру
OpenSSL это очень просто (нет)
 
 
<BR>
 
<BR>
   
  +
Задача:
Развертывание PKI на основе Vault
 
  +
* Собрать работающий кластер k8s из гавна и палок
  +
* Сделать его полезным и использовать в домашней сети для каких-то задач
  +
  +
  +
Шаги
  +
* Подготовить консул (нужен как бекенд для Vault хотя это не единственный вариант) [[Consul_Basic_Setup]]
  +
* Подготовить Vault (базовые настройки: [[Vault_Basic_Setup]]
  +
* Настройить PKI [[Vault_PKI_Kubernetes_the_hard_way_v2]]
  +
** Создать корневой СА [[Vault_PKI_Kubernetes_the_hard_way_v2_Root_CA]]
  +
** Создать тестовые роли и проверить работу [[Vault_PKI_Intermediate_ca_etcd_Roles_and_permissions_Kubernetes_the_hard_way_v2]]
  +
**
   
 
=Установка Vault=
 
=Установка Vault=
Предполагается что Vault уже установлен и настроен
+
Предполагается что Vault уже установлен и настроен ( в моем случае по адресу http://vault.home:8200 )
  +
  +
=Работа с Vault=
  +
Для создания endpoints потребуется токен с правами root и выставленная переменная '''VAULT_ADDR'''
  +
<PRE>
  +
export VAULT_ADDR=http://127.0.0.1:8200
  +
export VAULT_TOKEN="s.Yb1J2VamFyYoav3VVE2YQQ88"
  +
</PRE>
   
 
=PKI=
 
=PKI=
Строка 26: Строка 44:
 
Кроме того можно удлинить эту цепочку используя уже готовый СА и промежуточный СА и импортировав их в Vault (но примера тут нет - я не делал)
 
Кроме того можно удлинить эту цепочку используя уже готовый СА и промежуточный СА и импортировав их в Vault (но примера тут нет - я не делал)
   
==Включить PKI для корневого сертификата==
 
<PRE>
 
vault secrets enable \
 
-path=pki_root_ca \
 
-description="PKI Root CA" \
 
-max-lease-ttl="262800h" \
 
pki
 
</PRE>
 
==Создание корневого сертефиката (CA)==
 
===Конфигурация Vault===
 
* ВАЖНО: Тип определяет будет ли показан ключ от сертификата. В случае <B> internal</B> ключ показа не будет и сертификат можно будет использовать только в Vault
 
   
  +
* https://habr.com/ru/post/673730/
<PRE>
 
TYPE="exported"
 
#TYPE="internal"
 
   
  +
=Создание корневого CA=
vault write -format=json pki_root_ca/root/generate/${TYPE} \
 
  +
Создание корневого СА: [[Vault_PKI_Kubernetes_the_hard_way_v2_Root_CA]]
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
 
</PRE>
 
* ttl="262800h" - 30 лет
 
* В теории возможно использовать пре-созданный CA или даже цепочку - смотреть тут: https://groups.google.com/g/vault-tool/c/y4IcgiLBG4c
 
   
  +
=Создание промежуточных СА=
===Просмотр результата===
 
Результат работы команды (длинный вывод пропущен):
 
<PRE>
 
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
 
}
 
</PRE>
 
 
Корневой сертефикат самоподписаный. Поля 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
 
В целом можно использовать и корневой СА для создания конечных сертификатов но "лучшие собаководы" рекомендуют использовать промежуточный CA
  +
<BR>
 
  +
'''ВАЖНО''': В K8s используется множество разных CA, хотя большая часть документации об этом умалчивает - но каждый сервис может иметь свой собственный CA и подписанные им сертификаты, и именно так я и буду делать для лучшего понимания
===Конфигурация Vault===
 
  +
==Промежуточный CA etcd==
<PRE>
 
  +
Пример настройки прав и ролей и создания сертефикатов для etcd
vault secrets enable \
 
  +
[[Vault_PKI_Intermediate_ca_etcd_Kubernetes_the_hard_way_v2]]
-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=
Создание пользователей и ролей не относится непосредсвенно к настройке 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>
 
   
  +
[[Vault_PKI_Intermediate_ca_etcd_Roles_and_permissions_Kubernetes_the_hard_way_v2|Использование PKI для создания сертификатов]]
   
===Просмотр ролей===
 
<PRE>
 
vault list pki_intermediate_ca/roles
 
Keys
 
----
 
example-dot-home-client-crt
 
example-dot-home-server-crt
 
</PRE>
 
   
  +
Создание пользователей и ролей не относится непосредсвенно к настройке PKI но добавлено для полноты так как все равно надо настроить =)
<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>
 
<PRE>
Строка 964: Строка 111:
 
tidy_revocation_list=true
 
tidy_revocation_list=true
 
</PRE>
 
</PRE>
  +
 
=Проверка сертификатов с Nginx=
 
=Проверка сертификатов с Nginx=
 
Для проверки работы сертификатов настроим nginx как proxy. в качестве бекенда выступает сам Vault
 
Для проверки работы сертификатов настроим nginx как proxy. в качестве бекенда выступает сам Vault
Строка 995: Строка 143:
 
</PRE>
 
</PRE>
 
==Настройка Vault==
 
==Настройка 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
 
* Файл vault-dot-home-server-crt-policy.hlc

Текущая версия на 10:30, 9 октября 2022


Vault PKI for k8s

Эта статья основана на Vault_PKI и во многом дублирует ее, но тут я постарался подробно описать все применительно к "самодельному" домашнему кластеру

Задача:

  • Собрать работающий кластер k8s из гавна и палок
  • Сделать его полезным и использовать в домашней сети для каких-то задач


Шаги

Установка Vault

Предполагается что Vault уже установлен и настроен ( в моем случае по адресу http://vault.home:8200 )

Работа с Vault

Для создания endpoints потребуется токен с правами root и выставленная переменная VAULT_ADDR

export VAULT_ADDR=http://127.0.0.1:8200
export VAULT_TOKEN="s.Yb1J2VamFyYoav3VVE2YQQ88"

PKI

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

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

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


Создание корневого CA

Создание корневого СА: Vault_PKI_Kubernetes_the_hard_way_v2_Root_CA

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

В целом можно использовать и корневой СА для создания конечных сертификатов но "лучшие собаководы" рекомендуют использовать промежуточный CA
ВАЖНО: В K8s используется множество разных CA, хотя большая часть документации об этом умалчивает - но каждый сервис может иметь свой собственный CA и подписанные им сертификаты, и именно так я и буду делать для лучшего понимания

Промежуточный CA etcd

Пример настройки прав и ролей и создания сертефикатов для etcd Vault_PKI_Intermediate_ca_etcd_Kubernetes_the_hard_way_v2

Работа с PKI

Использование PKI для создания сертификатов


Создание пользователей и ролей не относится непосредсвенно к настройке 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-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

Прочие