Vault PKI Intermediate ca etcd Roles and permissions for real cluster Kubernetes the hard way v2
Вводная часть
Тут описывается создание сертификатов для 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
Получение серверного сертификата (для соединения с между серверами, peer-to-peer)
- Получать непосредственно на нодах
- на нодах меняются домены, роли и пользователи
Запускать на всех трех нодах, путь /etc/etcd/certs/server
один и тот же,
сразу делать бандл из сертификата и промежуточного СА
Стараемся делать путь и имена файлов одинаковыми что-бы конфиги отличались минимально
#!/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 ========
Вернуться к настройке ETCd
В этом месте уже есть все сертификаты для того что бы запустить etcd
с peer-to-peer SSL
Можно вернуться от выписывания сертификатов к настройке ETCd
Роли и пользователи для client-server сертификатов
- Для сертефиката который будет "клиентский-серверный":
Роли для клиент-серверного SSL
#!/bin/bash source ./00_env for AZ in $(seq 1 3); do DOMAIN="etcd.master.az${AZ}.k8s.cluster.home" NAME="${DOMAIN}-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},etcd.k8s.cluster.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=true \ server_flag=true \ enforce_hostnames=true \ key_usage="DigitalSignature,KeyEncipherment" \ ext_key_usage="ServerAuth" \ require_cn=true done
ВНЕЗАПНО оказалось что с новой версией etcd пришлось
- client_flag=true
- server_flag=true
- ext_key_usage="ServerAuth"
У меня нет пояснения почему так - в прошлых версиях client_flag=true
не требовался а сейчас возникает ошибка
WARNING: 2022/10/12 16:21:53 grpc: addrConn.createTransport failed to connect to {10.0.11.1:2379 <nil> 0 <nil>}. Err: connection error: desc = "transport: authentication handshake failed: remote error: tls: bad certificate". Reconnecting...
Создание политики, пользователя и привязка политики к пользователю
#!/bin/bash source ./00_env for AZ in $(seq 1 3); do DOMAIN="etcd.master.az${AZ}.k8s.cluster.home" NAME="${DOMAIN}-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
Просмотр созданных политик
#!/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
Получение серверного сертификата (для client-server соединений)
- Получать непосредственно на нодах
- на нодах меняются домены, роли и пользователи
Запускать на всех трех нодах, путь /etc/etcd/certs/server-to-client"
один и тот же,
сразу делать бандл из сертификата и промежуточного СА.
Внимательно следить - доменные имена и IP нужно подправить для каждой ноды! (AZ=1,2,3)
#!/bin/bash PKI_NAME="k8s_pki_intermediate_ca_for_service_etcd" #!/bin/bash PKI_NAME="k8s_pki_intermediate_ca_for_service_etcd" CERTS_PATH="/etc/etcd/certs/server-to-client" mkdir -p ${CERTS_PATH} AZ=1 DOMAIN="etcd.master.az${AZ}.k8s.cluster.home" BALANCER_DOMAIN="etcd.k8s.cluster.home" NAME="${DOMAIN}-server" IP="10.0.11.1" vault \ login \ -method=userpass \ username="${NAME}-user" \ password="${NAME}-password" echo "========" vault \ write \ -format=json \ ${PKI_NAME}/issue/${NAME}-role \ common_name="${DOMAIN}" \ alt_names="${DOMAIN},${BALANCER_DOMAIN}" \ ip_sans="${IP}" \ ca=false \ 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-to-client-key.pem ln -sf ${CERTS_PATH}/${DOMAIN}.pem ${CERTS_PATH}/etcd-server-to-client-crt.pem
Вернуться к настройке ETCd
В этом месте уже есть все сертификаты для того что бы запустить etcd
с client-server SSL
Можно вернуться от выписывания сертификатов к настойке ETCd
Роли и пользователи для клиентских сертификатов
Роли для получения клиентских сертификатов
#!/bin/bash source ./00_env for AZ in $(seq 1 3); do DOMAIN="etcd.master.az${AZ}.k8s.cluster.home" NAME="${DOMAIN}-client" 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" \ allow_subdomains=false \ max_ttl="87600h" \ key_bits="2048" \ key_type="rsa" \ allow_any_name=true \ allow_bare_domains=true \ allow_glob_domain=false \ allow_ip_sans=true \ allow_localhost=false \ client_flag=true \ server_flag=false \ enforce_hostnames=true \ key_usage="DigitalSignature,KeyEncipherment" \ ext_key_usage="ClientAuth" \ require_cn=true done
Создание политики, пользователя и привязка политики к пользователю
#!/bin/bash source ./00_env for AZ in $(seq 1 3); do DOMAIN="etcd.master.az${AZ}.k8s.cluster.home" NAME="${DOMAIN}-client" 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
Просмотр созданных политик
#!/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
Получение клиентского сертификата
- cn это имя пользователя и (пока не настроена дополнительная авторизация) это произвольное значение
- на нодах меняются домены, роли и пользователи
#!/bin/bash PKI_NAME="k8s_pki_intermediate_ca_for_service_etcd" CERTS_PATH="/etc/etcd/certs/client" mkdir -p ${CERTS_PATH} AZ=1 DOMAIN="etcd.master.az${AZ}.k8s.cluster.home" NAME="${DOMAIN}-client" USERNAME="master-${AZ}" vault \ login \ -method=userpass \ username="${NAME}-user" \ password="${NAME}-password" echo "========" vault \ write \ -format=json \ ${PKI_NAME}/issue/${NAME}-role \ common_name="${USERNAME}" \ ca=false \ ttl="43800h" \ > ${CERTS_PATH}/${USERNAME}.crt.json cat \ ${CERTS_PATH}/${USERNAME}.crt.json \ | jq -r '.data.private_key' > ${CERTS_PATH}/${USERNAME}.key cat \ ${CERTS_PATH}/${USERNAME}.crt.json \ | jq -r '.data.certificate' > ${CERTS_PATH}/${USERNAME}.pem cat \ ${CERTS_PATH}/${USERNAME}.crt.json \ | jq -r '.data.ca_chain[]' >> ${CERTS_PATH}/${USERNAME}.pem ln -sf ${CERTS_PATH}/${USERNAME}.key ${CERTS_PATH}/etcd-client-key.pem ln -sf ${CERTS_PATH}/${USERNAME}.pem ${CERTS_PATH}/etcd-client-crt.pem
openssl x509 -noout -text -in master-1.pem
Certificate: Data: ... Subject: C = Ukraine, L = Kharkov, street = Lui Pastera st 322 app. 311, postalCode = 61172, O = Home Network, OU = IT, CN = master-1 ...
Вернуться к настройке ETCd
В этом месте уже есть все сертификаты для того что бы запустить etcd
с peer-to-peer SSL
Можно вернуться от выписывания сертификатов к настройке ETCd
Сертификаты для авторизации с именем пользователя в ETCd
Дополнительная настройка PKI
Важно - разрешить произвольный CN (а не только валидные домены) allow_any_name=true
#!/bin/bash source ./00_env for AZ in $(seq 1 3); do DOMAIN="etcd.master.az${AZ}.k8s.cluster.home" NAME="${DOMAIN}-client" 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" \ allow_subdomains=false \ max_ttl="87600h" \ key_bits="2048" \ key_type="rsa" \ allow_any_name=true \ allow_bare_domains=true \ allow_glob_domain=false \ allow_ip_sans=true \ allow_localhost=false \ client_flag=true \ server_flag=false \ enforce_hostnames=true \ key_usage="DigitalSignature,KeyEncipherment" \ ext_key_usage="ClientAuth" \ require_cn=true done
В остальном настройки такие же как и в предыдущем случае
Получение сертификата для имени пользователя
#!/bin/bash PKI_NAME="k8s_pki_intermediate_ca_for_service_etcd" CERTS_PATH="/etc/etcd/certs/client" mkdir -p ${CERTS_PATH} AZ=1 DOMAIN="etcd.master.az${AZ}.k8s.cluster.home" NAME="${DOMAIN}-client" USERNAME="kubeapiserver" echo "========" vault \ write \ -format=json \ ${PKI_NAME}/issue/${NAME}-role \ common_name="${USERNAME}" \ ca=false \ ttl="43800h" \ > ${CERTS_PATH}/${USERNAME}.crt.json cat \ ${CERTS_PATH}/${USERNAME}.crt.json \ | jq -r '.data.private_key' > ${CERTS_PATH}/${USERNAME}.key cat \ ${CERTS_PATH}/${USERNAME}.crt.json \ | jq -r '.data.certificate' > ${CERTS_PATH}/${USERNAME}.pem cat \ ${CERTS_PATH}/${USERNAME}.crt.json \ | jq -r '.data.ca_chain[]' >> ${CERTS_PATH}/${USERNAME}.pem