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

Получение серверного сертификата (для соединения с между серверами, 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