Etcd: различия между версиями
Sirmax (обсуждение | вклад) |
Sirmax (обсуждение | вклад) |
||
Строка 194: | Строка 194: | ||
=Client SSL= |
=Client SSL= |
||
Следующий шаг - добавить шифрование клиентских соединений |
Следующий шаг - добавить шифрование клиентских соединений |
||
+ | <BR> |
||
+ | Тут есть путаница - "клиентский-серверный" и "совсем клиентский" сертефикаты |
||
+ | * "клиентский-серверный" - тот что устанавливается на сервере ETCD для того что бы обеспечить SSL клиентам |
||
+ | * "совсем клиентский" - тот с которым авторизуются клиенты |
||
+ | ==настройка PKI для Client SSL== |
||
+ | Со стороны ETCD сетрефикаты - "серверные", со стороны клиентов - "клиентские", по тому требуется создать в Vault PKI два дополнительных endpoint |
||
+ | |||
+ | |||
+ | * Для сертефиката который будет "клиентский-серверный": |
||
+ | <PRE> |
||
+ | vault write pki_intermediate_ca/roles/etc-az-k8s-home-server-only-crt \ |
||
+ | country="Ukraine" \ |
||
+ | locality="Kharkov" \ |
||
+ | street_address="Lui Pastera st 322 app. 311"\ |
||
+ | postal_code="61172" \ |
||
+ | organization="Home Network" \ |
||
+ | ou="IT" \ |
||
+ | allowed_domains="etcd1.home,etcd2.home,etcd3.home,etcd.home,etcd.az1.k8s.home,etcd.az2.k8s.home,etcd.az3.k8s.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> |
||
+ | Обратить внимаене что это чисто серверный сертефикат: |
||
+ | * client_flag=false |
||
+ | * ext_key_usage="ServerAuth" |
||
+ | |||
+ | |||
+ | "совсем клиентский": |
||
+ | <PRE> |
||
+ | vault write pki_intermediate_ca/roles/etc-az-k8s-home-client-only-crt \ |
||
+ | country="Ukraine" \ |
||
+ | locality="Kharkov" \ |
||
+ | street_address="Lui Pastera st 322 app. 311"\ |
||
+ | postal_code="61172" \ |
||
+ | organization="Home Network" \ |
||
+ | ou="IT" \ |
||
+ | allowed_domains="etcd1.home,etcd2.home,etcd3.home,etcd.home,etcd.az1.k8s.home,etcd.az2.k8s.home,etcd.az3.k8s.home" \ |
||
+ | allow_subdomains=false \ |
||
+ | 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> |
||
+ | Тут - только клиентский сертефикат |
||
+ | * client_flag=true |
||
+ | * server_flag=false |
||
+ | * ext_key_usage="ClientAuth" |
||
=Client SSL= |
=Client SSL= |
Версия 11:03, 23 октября 2021
Etcd
Это часть моего изучения k8s the hard way
но может использоваться и отдельно
Требования
- 3 ноды raspberry pi установленные и настроенные, имеющие коннективити друг с другом
- установленный и настроенный PKI на основе Hashicorp Vault (в примере - по адресу http://vault.home)
- Настроенный DNS и созданы записи для всех доменов в примере (в моем случае DNS поднят на MikroTik)
Установка
- мне НЕ удалось ни найти ни собрать более свежую версию чем была доступна в пакетах дистрибутива
- установить на всех трех нодах
apt -y install etcd-server etcd-client etcd
dpkg -l | grep etcd iU etcd 3.2.26+dfsg-3 all Transitional package for etcd-client and etcd-server ii etcd-client 3.2.26+dfsg-3 armhf highly-available key value store -- client iF etcd-server 3.2.26+dfsg-3 armhf highly-available key value store -- daemon
- TODO: проверить кросс-компиляцию для ARM
Подготовка SSL сертификатов
Согласно документации (https://etcd.io/docs/v3.5/op-guide/security/) etcd сертификаты используются в двух независимых настройках:
- Коммуникация между нодами кластера
- Коммуникация между кластером и клиентом
Peer-to-peer SSL
Для того что бы настроить SSL потребуются сертификаты для соответствующих доменов. Так как сертификаты во взаимодействии нод кластера используются как клиентские и как серверные, то нужна соответствующая настройка PLI
настройка PKI для peer-to-peer SSL
- Нужен клиент Vault
- В примере используется рутовый токен (нужен ТОЛЬКО для создания "роли", но используется везде в примерах)
Для обновления сертификатов будет добавлен пользователь или другой способ авторизации и права будут ограничены
export VAULT_ADDR=http://vault.home:8200 export VAULT_TOKEN=<some-token-here> vault write pki_intermediate_ca/roles/etc-az-k8s-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="etcd1.home,etcd2.home,etcd3.home,etcd.home,etcd.az1.k8s.home,etcd.az2.k8s.home,etcd.az3.k8s.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,ClientAuth" \ require_cn=true
В скрипте выще важно следующее
- etc-az-k8s-home-server-crt имя роли - по сути произвольная строка которая просто определяет endpoint (используется ниже)
- allowed_domains="etcd1.home,etcd2.home,etcd3.home,etcd.home,etcd.az1.k8s.home,etcd.az2.k8s.home,etcd.az3.k8s.home" - список доменов для которых можно выписывать сертефикаты используя этот endpoint. В моем случае изначально планировалось использовать домены etcdX.home но так как настройка "а-ля мультизонный кластер" то домер решил изменить
ВАЖНО: Домены пречислять через запятую без пробелов иначе не работает (как минимум в моей версии Vault)
- allow_subdomains=false - не разрешать создавать сабдомены
- client_flag=true - сертификат может использоваться как клиентский
- server_flag=true - сертификат может использоваться как серверный
- ext_key_usage="ServerAuth,ClientAuth" - расширения
Если попробовать создать только серверный сертификат то возникает ошибка SSL которая в общем-то об этом и говорит и ничего не работает
Создание сертификатов для peer-to-peer
Пример для одного домена, для остальных аналогично
export VAULT_ADDR=http://vault.home:8200 export VAULT_TOKEN=<some-token-here> domain="etcd.az1.k8s.home" vault \ write \ -format=json pki_intermediate_ca/issue/etc-az-k8s-home-server-crt \ common_name="${domain}" \ ttl="43800h" > ${domain}.crt.json
- issue/etc-az-k8s-home-server-crt - имя роли которое указано на предыдущем шаге
- используется рутовый токен который имеет все права (но это только для примера что бы пропустить "лишние" шаги)
Полученный файл etcd.az1.k8s.home.crt.json:
{ "request_id": "0454e996-7bbc-d3ca-8830-cc2d544b2763", "lease_id": "", "lease_duration": 0, "renewable": false, "data": { "ca_chain": [ "-----BEGIN CERTIFICATE----- пропущено -----END CERTIFICATE-----" ], "certificate": "-----BEGIN CERTIFICATE----- пропущено -----END CERTIFICATE-----", "expiration": 1792583899, "issuing_ca": "-----BEGIN CERTIFICATE----- пропущено -----END CERTIFICATE-----", "private_key": "-----BEGIN RSA PRIVATE KEY----- пропущено -----END RSA PRIVATE KEY-----", "private_key_type": "rsa", "serial_number": "3b:f4:6d:6d:b8:47:38:9f:7b:4d:dc:11:89:d9:63:ff:74:e6:fd:ed" }, "warnings": null }
Из полученного файла подготовить отдельно файлы сертификатов:
#!/bin/bash domain="etcd.az1.k8s.home" mkdir -p /etc/etcd/certs/server cat \ ${domain}.crt.json \ | jq -r '.data.private_key' > /etc/etcd/certs/server/${domain}.key cat \ ${domain}.crt.json \ | jq -r '.data.certificate' > /etc/etcd/certs/server/${domain}.pem cat \ ${domain}.crt.json \ | jq -r '.data.ca_chain[]' >> /etc/etcd/certs/server/${domain}.pem
Обратить внимание: так как сертефикат подписан НЕ корневым а промежуточным центром сертефикации то в файл сертификата требуется добавить промежуточный сертефикат (поле '.data.ca_chain[]' в json)
Тестовый запуск
В целом этого достаточно что бы запустить etcd (но клиентские соединения будут нешифрованными и без авторизации)
Скрипт запуска (на всех трех нодах отличаются домены и адреса):
export ETCD_UNSUPPORTED_ARCH=arm /usr/bin/etcd \ --debug \ --name=etcd-az-1 \ --listen-peer-urls=https://10.240.1.2:2380 \ --listen-client-urls=http://10.240.1.2:2379,http://127.0.0.1:2379 \ --advertise-client-urls=http://etcd.az1.k8s.home:2379 \ --initial-advertise-peer-urls=https://etcd.az1.k8s.home:2380 \ --initial-cluster-token=etcd.az1.k8s.home \ --initial-cluster etcd-az-1=https://etcd.az1.k8s.home:2380,etcd-az-2=https://etcd.az2.k8s.home:2380,etcd-az-3=https://etcd.az3.k8s.home:2380 \ --initial-cluster-state=new \ --data-dir=/var/lib/etcd \ --peer-client-cert-auth \ --peer-cert-file=/etc/etcd/certs/server/etcd.az1.k8s.home.pem \ --peer-key-file=/etc/etcd/certs/server/etcd.az1.k8s.home.key \ --peer-trusted-ca-file=/etc/etcd/certs/rootCA.pem
Запускать на всех трех нодах!
Проверка подключения клиента без SSL
ETCDCTL_API=3 etcdctl --debug --endpoints=http://etcd.az1.k8s.home:2379 member list
Вывод команды разбит на 2 части - дебаг и собственно вывод
из вывода команды видно что все три ноды в кластере
INFO: 2021/10/22 15:50:14 parsed scheme: "" INFO: 2021/10/22 15:50:14 scheme "" not registered, fallback to default scheme INFO: 2021/10/22 15:50:14 ccResolverWrapper: sending new addresses to cc: [{etcd.az1.k8s.home:2379 0 <nil>}] INFO: 2021/10/22 15:50:14 balancerWrapper: got update addr from Notify: [{etcd.az1.k8s.home:2379 <nil>}] INFO: 2021/10/22 15:50:14 clientv3/balancer: pin "etcd.az1.k8s.home:2379" INFO: 2021/10/22 15:50:14 balancerWrapper: got update addr from Notify: [{etcd.az1.k8s.home:2379 <nil>}]
b7a875ba8d83c06, started, etcd-az-3, https://etcd.az3.k8s.home:2380, http://etcd.az3.k8s.home:2379 489c4054ed342d1a, started, etcd-az-2, https://etcd.az2.k8s.home:2380, http://etcd.az2.k8s.home:2379 db4ea93d7a019672, started, etcd-az-1, https://etcd.az1.k8s.home:2380, http://etcd.az1.k8s.home:2379
Client SSL
Следующий шаг - добавить шифрование клиентских соединений
Тут есть путаница - "клиентский-серверный" и "совсем клиентский" сертефикаты
- "клиентский-серверный" - тот что устанавливается на сервере ETCD для того что бы обеспечить SSL клиентам
- "совсем клиентский" - тот с которым авторизуются клиенты
настройка PKI для Client SSL
Со стороны ETCD сетрефикаты - "серверные", со стороны клиентов - "клиентские", по тому требуется создать в Vault PKI два дополнительных endpoint
- Для сертефиката который будет "клиентский-серверный":
vault write pki_intermediate_ca/roles/etc-az-k8s-home-server-only-crt \ country="Ukraine" \ locality="Kharkov" \ street_address="Lui Pastera st 322 app. 311"\ postal_code="61172" \ organization="Home Network" \ ou="IT" \ allowed_domains="etcd1.home,etcd2.home,etcd3.home,etcd.home,etcd.az1.k8s.home,etcd.az2.k8s.home,etcd.az3.k8s.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
Обратить внимаене что это чисто серверный сертефикат:
- client_flag=false
- ext_key_usage="ServerAuth"
"совсем клиентский":
vault write pki_intermediate_ca/roles/etc-az-k8s-home-client-only-crt \ country="Ukraine" \ locality="Kharkov" \ street_address="Lui Pastera st 322 app. 311"\ postal_code="61172" \ organization="Home Network" \ ou="IT" \ allowed_domains="etcd1.home,etcd2.home,etcd3.home,etcd.home,etcd.az1.k8s.home,etcd.az2.k8s.home,etcd.az3.k8s.home" \ allow_subdomains=false \ 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
Тут - только клиентский сертефикат
- client_flag=true
- server_flag=false
- ext_key_usage="ClientAuth"