Vault PKI Intermediate ca etcd Roles and permissions for real cluster Kubernetes the hard way v2
Материал из noname.com.ua
Вводная часть
Тут описывается создание сертификатов для etcd
Это продолжение Статьи про создание промежуточного СА
Упрощение работы
Путь к PKI (k8s_pki_intermediate_ca_for_service_etcd) встречается многократно, и он вынесен в переменную
cat 00_env
export PKI_NAME="k8s_pki_intermediate_ca_for_service_etcd"
Роли и пользователи для peer-to-peer сертификатов
В кластере участвуют три сервера, соответственно для каждого из них требуется отдельные настройки - роль, пользователь ...
Роли для получения peer-to-peer сертификатов
Три зоны - три роли, по одной для каждого сервера
client_flag=true server_flag=true enforce_hostnames=true key_usage="DigitalSignature,KeyEncipherment" ext_key_usage="ClientAuth,ServerAuth"
#!/bin/bash source ./00_env for AZ in $(seq 1 3); do DOMAIN="etcd.master.az${AZ}.k8s.cluster.home" NAME="${DOMAIN}-client-and-server" vault \ write \ ${PKI_NAME}/roles/${NAME}-role \ country="Ukraine" \ locality="Kharkov" \ street_address="Lui Pastera st 322 app. 311"\ postal_code="61172" \ organization="Home Network" \ ou="IT" \ allowed_domains="${DOMAIN}" \ 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=true \ server_flag=true \ enforce_hostnames=true \ key_usage="DigitalSignature,KeyEncipherment" \ ext_key_usage="ClientAuth,ServerAuth" \ require_cn=true done
Success! Data written to: k8s_pki_intermediate_ca_for_service_etcd/roles/etcd.master.az1.k8s.cluster.home-client-and-server-role Success! Data written to: k8s_pki_intermediate_ca_for_service_etcd/roles/etcd.master.az2.k8s.cluster.home-client-and-server-role Success! Data written to: k8s_pki_intermediate_ca_for_service_etcd/roles/etcd.master.az3.k8s.cluster.home-client-and-server-role
Создание политики, пользователя и привязка политики к пользователю
#!/bin/bash source ./00_env for AZ in $(seq 1 3); do DOMAIN="etcd.master.az${AZ}.k8s.cluster.home" NAME="${DOMAIN}-client-and-server" cat << EOF > ${NAME}-policy.hlc path "${PKI_NAME}/issue/${NAME}-role" { capabilities = ["read", "create", "list", "update"] } EOF vault \ policy \ write \ ${NAME}-policy \ ${NAME}-policy.hlc vault \ write \ auth/userpass/users/${NAME}-user \ password=${NAME}-password \ policies=" ${NAME}-policy,default" done
Success! Uploaded policy: etcd.master.az1.k8s.cluster.home-client-and-server-policy Success! Data written to: auth/userpass/users/etcd.master.az1.k8s.cluster.home-client-and-server-user Success! Uploaded policy: etcd.master.az2.k8s.cluster.home-client-and-server-policy Success! Data written to: auth/userpass/users/etcd.master.az2.k8s.cluster.home-client-and-server-user Success! Uploaded policy: etcd.master.az3.k8s.cluster.home-client-and-server-policy Success! Data written to: auth/userpass/users/etcd.master.az3.k8s.cluster.home-client-and-server-user
Просмотр созданных политик
#!/bin/bash source ./00_env echo "---------ROLES---------------------" vault \ list \ ${PKI_NAME}/roles echo "---------USERS---------------------" vault \ list \ auth/userpass/users echo "------------------------------" for AZ in $(seq 1 3); do DOMAIN="etcd.master.az${AZ}.k8s.cluster.home" NAME="${DOMAIN}-client-and-server" vault \ policy \ read \ ${NAME}-policy vault \ read \ auth/userpass/users/${NAME}-user done
Получения сертефикатов
- Получать непосредственно на нодах
- на нодах меняются домены, роли и пользователи
Получение серверного сертефиката
#!/bin/bash source ./00_env mkdir -p /etc/etcd/server/ AZ=1 DOMAIN="etcd.master.az${AZ}.k8s.cluster.home" NAME="${DOMAIN}-client-and-server" vault \ login \ -method=userpass \ username="${NAME}-user" \ password="${NAME}-password" echo "========" vault \ write \ -format=json \ ${PKI_NAME}/issue/${NAME}-role \ common_name="${DOMAIN}" \ ttl="43800h" \ > /etc/etcd/server/${DOMAIN}.crt.json
Получение сертификата
#!/bin/bash PKI_NAME="k8s_pki_intermediate_ca_for_service_etcd" CERTS_PATH="/etc/etcd/certs/server" mkdir -p ${CERTS_PATH} AZ=1 DOMAIN="etcd.master.az${AZ}.k8s.cluster.home" NAME="${DOMAIN}-client-and-server" vault \ login \ -method=userpass \ username="${NAME}-user" \ password="${NAME}-password" echo "========" vault \ write \ -format=json \ ${PKI_NAME}/issue/${NAME}-role \ common_name="${DOMAIN}" \ ttl="43800h" \ > ${CERTS_PATH}/${DOMAIN}.crt.json cat \ ${CERTS_PATH}/${DOMAIN}.crt.json \ | jq -r '.data.private_key' > ${CERTS_PATH}/${DOMAIN}.key cat \ ${CERTS_PATH}/${DOMAIN}.crt.json \ | jq -r '.data.certificate' > ${CERTS_PATH}/${DOMAIN}.pem cat \ ${CERTS_PATH}/${DOMAIN}.crt.json \ | jq -r '.data.ca_chain[]' >> ${CERTS_PATH}/${DOMAIN}.pem ln -sf ${CERTS_PATH}/${DOMAIN}.key ${CERTS_PATH}/etcd-server-key.pem ln -sf ${CERTS_PATH}/${DOMAIN}.pem ${CERTS_PATH}/etcd-server-crt.pem
Key Value --- ----- token s.7DfyaDzZZOb9fkV4NU8xR0Gw token_accessor cChs7RffaXPyrtLVmV9VGW8b token_duration 768h token_renewable true token_policies ["default" "etcd.master.az1.k8s.cluster.home-client-and-server-policy"] identity_policies [] policies ["default" "etcd.master.az1.k8s.cluster.home-client-and-server-policy"] token_meta_username etcd.master.az1.k8s.cluster.home-client-and-server-user ========
Получение клиентского сертефиката
Проверка прав (негативный сценарий)
С "серверным" пользователем - нет прав
source ./00_env vault \ login \ -method=userpass \ username=example-dot-home-server-crt-user \ password=server
Success! You are now authenticated. The token information displayed below is already stored in the token helper. You do NOT need to run "vault login" again. Future Vault requests will automatically use this token. Key Value --- ----- token s.P9nYzZ3Pev2IeNKaUYvDIDdt token_accessor AbXtLIzNhYJRvv6paZr3U6cn 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_NAME}/issue/example-dot-home-client-crt \ common_name="vault.example.home" \ alt_names="pki.example.home" \ ttl="43800h" > vault.example.home-client.crt
Error writing data to k8s_pki_intermediate_ca_for_service_etcd/issue/example-dot-home-client-crt: Error making API request. URL: PUT http://127.0.0.1:8200/v1/k8s_pki_intermediate_ca_for_service_etcd/issue/example-dot-home-client-crt Code: 403. Errors: * 1 error occurred: * permission denied
Результат соответствует ожидаемому.
Получение клиентского сертификата c правильным пользователем
vault \ login \ -method=userpass \ username=example-dot-home-any-crt-user \ password=any vault \ write \ -format=json \ ${PKI_NAME}/issue/example-dot-home-client-crt \ common_name="vault.example.home" \ alt_names="pki.example.home" \ ttl="43800h" > vault.example.home-client.crt.json Success! You are now authenticated. The token information displayed below is already stored in the token helper. You do NOT need to run "vault login" again. Future Vault requests will automatically use this token. Key Value --- ----- token s.vAKcP6hGLv9OHkm8ToBHFq5M token_accessor OoNShUinoMhne5s8scFcZ0Hm token_duration 768h token_renewable true token_policies ["default" "example-dot-home-client-crt-policy" "example-dot-home-server-crt-policy"] identity_policies [] policies ["default" "example-dot-home-client-crt-policy" "example-dot-home-server-crt-policy"] token_meta_username example-dot-home-any-crt-user
Проверка полученного результата
cat vault.example.home-client.crt.json | jq -r '.data.certificate' > vault.example.home-client.crt cat vault.example.home-client.crt.json | jq -r '.data.private_key' > vault.example.home-client.key
X509v3 Extended Key Usage: TLS Web Client Authentication
openssl x509 -noout -text -in certificate_client.pem <PRE> Certificate: Data: Version: 3 (0x2) Serial Number: 51:de:46:e0:72:1e:2b:28:30:3b:9e:94:f4:da:71:f8:19:5e:26:6d Signature Algorithm: sha256WithRSAEncryption Issuer: C = Ukraine, L = Kharkov, street = Lui Pastera st. 322 app. 131, postalCode = 61172, O = K8s The Hardest Way Labs, OU = IT, CN = Intermediate CA for service ETCd Validity Not Before: Oct 8 16:53:43 2022 GMT Not After : Oct 7 16:54:10 2027 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: 00:c3:21:f6:55:f9:f0:a7:19:52:b9:22:a6:9a:99: ... 05:e5 Exponent: 65537 (0x10001) X509v3 extensions: X509v3 Key Usage: critical Digital Signature X509v3 Extended Key Usage: TLS Web Client Authentication X509v3 Subject Key Identifier: C9:F1:9F:83:D7:0B:B8:F2:7E:BB:84:D1:FE:6F:7E:75:7B:40:F4:86 X509v3 Authority Key Identifier: keyid:60:41:31:79:58:90:A9:63:62:C2:26:FD:8F:02:B6:07:1A:1D:5C:50 Authority Information Access: CA Issuers - URI:http://vault.home:8200/v1/k8s_pki_intermediate_ca_for_service_etcd/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/k8s_pki_intermediate_ca_for_service_etcd/crl Signature Algorithm: sha256WithRSAEncryption 94:bb:a8:54:41:86:16:75:06:e7:fb:5a:5f:e0:56:61:5d:ff: ... 3e:56:1a:6f
Проверка полученного результата
Расширенная проверка - проверить что сертификат нельзя использовать в качестве серверного Конфиг nginx не отличается ничем кроме собственно содержимого сертификата
- Ответ собственно и говорит об этом - unsupported certificate purpose, клиентский сертификат не оч
curl: (60) SSL certificate problem: unsupported certificate purpose 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.
Проверка прав для пользователя any
- работает каки ожидалось - можно получить сертификаты как для сервера так и для клиента
#!/bin/bash source ./00_env unset VAULT_TOKEN vault \ login \ -method=userpass \ username=example-dot-home-any-crt-user \ password=any vault \ write \ -format=json \ ${PKI_NAME}/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_NAME}/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