Въведение в Hashicorp Consul’s Kubernetes Авторизация

Въведение в Hashicorp Consul’s Kubernetes Авторизация

Всичко е вярно, след излизането Hashicorp Consul 1.5.0 в началото на май 2019 година в Consul можем да правим авторизация на приложения и услуги, стартирани в Kubernetes, нативно.

В това ръководство стъпка по стъпка ще създадем POC (Проверка на концепцията (Proof of concept, PoC — доказателство [осъществимост] на концепцията — бел. прев.), демонстрирайки тази нова функция. Очакват се основни знания за Kubernetes и Hashicorp’s Consul. И макар че можете да използвате всяка облачна платформа или локална среда, в това ръководство ще използваме Google’s Cloud Platform.

Преглед

Ако преминем към документацията на Consul относно неговия метод за авторизация, ще получим кратък преглед на целта и вариантите на използване, както и някои технически подробности и общ преглед на логиката. Настоятелно препоръчвам да я прочетете поне веднъж, преди да продължите, тъй като сега ще обяснявам и разглеждам всичко.

Въведение в Hashicorp Consul’s Kubernetes Авторизация

Схема 1: Официален преглед на метода за авторизация на Consul

Нека да погледнем в документацията за конкретния метод за авторизация на Kubernetes.

Разбира се, там има полезна информация, но няма ръководство за това как всъщност да се използва всичко това. Затова, като всеки разумен човек, вие преровявате Интернет в търсене на ръководство. А после… Ами, неуспех. Така става. Нека да го коригираме.

Преди да преминем към създаването на нашия POC, нека се върнем към прегледа на методите за авторизация на Consul (Схема 1) и да го уточним в контекста на Kubernetes.

Архитектура

В това ръководство ще създадем Consul-сървър на отделна машина, който ще взаимодействат с кластера Kubernetes с инсталиран клиент Consul. След това ще създадем нашето фиктивно приложение в пода и ще използваме нашия настроен метод за авторизация, за да четем от нашето Consul key/value хранилище.

Схемата по-долу подробно показва архитектурата, която създаваме в това ръководство, както и логиката на метода за авторизация, която ще бъде обяснена по-късно.

Въведение в Hashicorp Consul’s Kubernetes Авторизация

Схема 2: Преглед на метода за авторизация в Kubernetes

Небольшо уточнение: Consul-сървърът не е необходимо да бъде извън кластера Kubernetes, за да работи. Но да, той може както да бъде, така и да не бъде.

Така че, взимайки схемата на Consul (Схема 1) и прилагаща я към Kubernetes, получаваме схемата по-горе (Схема 2), и логиката ще бъде следната:

  1. Към всеки под ще бъде прикрепен служебен акаунт, съдържащ JWT токен, генериран и известен на Kubernetes. Този токен също се вмъква в пода по подразбиране.
  2. Нашето приложение или услуга в пода инициира команда за вход в нашия Consul клиент. В заявката за вход ще бъде посочен нашият токен и името на специално създаденото метод на авторизация (тип Kubernetes). Тази стъпка № 2 отговаря на стъпка 1 от схемата на Consul (Схема 1).
  3. Нашият Consul клиент след това ще изпрати тази заявка на нашия Consul сървър.
  4. МАГИЯ! Именно тук Consul сървърът проверява автентичността на заявката, събира информация за идентичността и я сравнява с каквито и да било свързани предварително зададени правила. По-долу ще има друга схема, за да илюстрира това. Тази стъпка отговаря на стъпки 3, 4 и 5 от прегледната схема на Consul (Схема 1).
  5. Нашият Consul сървър генерира Consul токен с разрешения в съответствие с посочените от нас правила на метода на авторизация (които сме задали) спрямо идентичността на запитващия. След това той ще изпрати този токен обратно. Това отговаря на стъпка 6 от схемата на Consul (Схема 1).
  6. Нашият Consul клиент пренасочва токена към запитващото приложение или услуга.

Нашето приложение или услуга сега могат да използват този Consul токен, за да взаимодействат с нашите данни от Consul, както е определено от разрешенията на токена.

Магията е разкрита!

За тези от вас, които не се задоволяват само с заек из шапка и искат да знаят как работи… позволете ми да "покажа колко дълбока е заячата дупка».

Както беше споменато по-рано, нашата "магическа" стъпка (Схема 2: Стъпка 4) е, че Consul сървърът проверява автентичността на заявката, събира информация и я сравнява с каквито и да било свързани предварително зададени правила. Тази стъпка отговаря на стъпки 3, 4 и 5 от прегледната схема на Consul (Схема 1). По-долу е схема (Схема 3), чиято цел е наглядно да покаже какво всъщност се случва под капака на конкретния метод на авторизация Kubernetes.

Въведение в Hashicorp Consul’s Kubernetes Авторизация

Схема 3: Магията разкрита!

  1. Като отправна точка, нашият Consul клиент пренасочва заявката за вход към нашия Consul сървър с токена на акаунта в Kubernetes и конкретното име на инстанцията на метода на авторизация, който е бил създаден по-рано. Тази стъпка отговаря на стъпка 3 от предишното обяснение на схемата.
  2. Сега на Consul-сервера (или лидера) е необходимо да провери автентичността на полученото токен. Затова той ще се консултира с кластер Kubernetes (чрез клиента Consul) и, при наличието на съответни разрешения, ние ще установим дали токенът е автентичен и на кого принадлежи.
  3. След това проверената заявка се връща към Consul-лидера и на сървера Consul се извършва търсене на инстанция на метода за удостоверяване с посоченото име от заявката за вход в системата (и тип Kubernetes).
  4. Consul-лидерът определя посочената инстанция на метода за удостоверяване (ако е намерена) и прочита набора от правила, които са прикрепени към нея. След това той чете тези правила и ги сравнява с проверените атрибути на идентичността.
  5. Ура! Преминаваме към стъпка 5 от предишното обяснение на схемата.

Стартирайте Consul-сървера на обикновена виртуална машина.

От този момент нататък основно ще давам инструкции за създаване на този POC, често в точки, без обяснителни цели изречения. Както беше отбелязано по-рано, ще използвам GCP за създаване на цялата инфраструктура, но можете да създадете същата инфраструктура и на друго място.

  • Стартирайте виртуалната машина (инстанция / сървър).

Въведение в Hashicorp Consul’s Kubernetes Авторизация

  • Създайте правило за firewall (група за сигурност в AWS):
  • Обичам да присвоявам същото име на машината и на правилото и мрежовия таг, в този случай „skywiz-consul-server-poc“.
  • Намерете IP адреса на локалния си компютър и го добавете в списъка с изходящи IP адреси, за да можем да получим достъп до интерфейса на потребителя (UI).
  • Отворете порт 8500 за UI. Натиснете Create (Създаване). Скоро ще променим отново този firewall [линк].
  • Добавете правило за firewall към инстанцията. Върнете се на таблото за управление на VM на Consul-сървера и добавете „skywiz-consul-server-poc“ в полето за мрежови тагове. Натиснете Save (Записване).

Въведение в Hashicorp Consul’s Kubernetes Авторизация

  • Инсталирайте Consul на виртуалната машина, проверете тук. Помнете, че ви трябва версия Consul ≥ 1.5 [линк]
  • Нека създадем single node Consul — конфигурацията е следната.

groupadd --system consul
useradd -s /sbin/nologin --system -g consul consul
mkdir -p /var/lib/consul
chown -R consul:consul /var/lib/consul
chmod -R 775 /var/lib/consul
mkdir /etc/consul.d
chown -R consul:consul /etc/consul.d

  • По-подробно ръководство за инсталиране на Consul и настройка на кластер от 3 нода можете да намерите тук. тук..
  • Създайте файла /etc/consul.d/agent.json по следния начин [линк]:

### /etc/consul.d/agent.json
{
 "acl" : {
 "enabled": true,
 "default_policy": "deny",
 "enable_token_persistence": true
 }
}

  • Стартирайте нашия Consul-сървър:

consul agent 
-server 
-ui 
-client 0.0.0.0 
-data-dir=/var/lib/consul 
-bootstrap-expect=1 
-config-dir=/etc/consul.d

  • Трябва да видите много изходни данни и в крайна сметка „… актуализация блокирана от ACLs“.
  • Намерете външния IP адрес на Consul сървъра и отворете браузър с този IP адрес на порт 8500. Убедете се, че UI се отваря.
  • Опитайте да добавите няколко ключ/стойност. Трябва да получите грешка. Това е, защото сме заредили Consul сървъра с ACL и сме забранили всички правила.
  • Върнете се в терминала на Consul сървъра и стартирайте процеса на заден план или по друг начин, за да работи, и въведете следното:

consul acl bootstrap

  • Намерете стойността „SecretID“ и се върнете в UI. На раздела „ACL“ въведете секретния идентификатор на токена, който току-що копирахте. Копирайте SecretID още някъде, той ще ни бъде нужен по-късно.
  • Сега добавете двойка ключ/стойност. За този POC ще добавим следното: ключ: „custom-ns/test_key“, стойност: „Аз съм в папката custom-ns!“

Стартиране на Kubernetes клъстер за нашето приложение с Consul клиент като Daemonset

  • Създайте K8s (Kubernetes) клъстер. Ще го създадем в същата зона като сървера, за по-бърз достъп, и затова можем да използваме същата подсет, за да се свържем с вътрешни IP адреси. Ще го наречем „skywiz-app-with-consul-client-poc“.

Въведение в Hashicorp Consul’s Kubernetes Авторизация

  • Като забележка, ето хубаво ръководство, с което се сблъсках, когато настройвах POC Consul клъстер с Consul Connect.
  • Ние също така ще използваме Hashicorp helm chart с разширен файл за стойности.
  • Инсталирайте и конфигурирайте Helm. Стъпки за конфигурация:

kubectl create serviceaccount tiller --namespace kube-system
kubectl create clusterrolebinding tiller-admin-binding 
   --clusterrole=cluster-admin --serviceaccount=kube-system:tiller
. /helm init --service-account=tiller
. /helm update

### poc-helm-consul-values.yaml
global:
 enabled: false
 image: "consul:latest"
# Expose the Consul UI through this LoadBalancer
ui:
 enabled: false
# Allow Consul to inject the Connect proxy into Kubernetes containers
connectInject:
 enabled: false
# Configure a Consul client on Kubernetes nodes. GRPC listener is required for Connect.
client:
 enabled: true
 join: ["<PRIVATE_IP_CONSUL_SERVER>"]
 extraConfig: |
{
  "acl" : {
 "enabled": true,   
 "default_policy": "deny",   
 "enable_token_persistence": true 
  }
}
# Minimal Consul configuration. Not suitable for production.
server:
 enabled: false
# Sync Kubernetes and Consul services
syncCatalog:
 enabled: false

  • Прилагане на helm chart:

. /helm install -f poc-helm-consul-values.yaml . /consul-helm - name skywiz-app-with-consul-client-poc

  • При опит за стартиране, ще са необходими разрешения за Consul сървъра, така че да добавим такива.
  • Обърнете внимание на „диапазона на адресите на Pod“, разположен на таблото на клъстера, и се върнете към нашето правило за защитна стена „skywiz-consul-server-poc“.
  • Добавете диапазона от адреси за пода в списъка с IP адреси и отворете портове 8301 и 8300.

Въведение в Hashicorp Consul’s Kubernetes Авторизация

  • Отидете на Consul UI и след няколко минути ще видите, че нашият клъстер ще се появи на раздела с възли.

Въведение в Hashicorp Consul’s Kubernetes Авторизация

Настройка на метода за удостоверяване чрез интеграция на Consul с Kubernetes

  • Върнете се в терминала на Consul сървъра и експортирайте токена, който запазихте по-рано:

export CONSUL_HTTP_TOKEN=

  • Ще ни е необходима информация от нашия Kubernetes клъстър, за да създадем инстанция на метода за удостоверяване:
  • kubernetes-host

kubectl get endpoints | grep kubernetes

  • kubernetes-service-account-jwt

kubectl get sa -consul-client -o yaml | grep "- name:"
kubectl get secret  -o yaml | grep token:

  • Токенът е кодирана в base64, затова го разкодирайте с любимия си инструмент [линк]
  • kubernetes-ca-cert

kubectl get secret  -o yaml | grep ca.crt:

  • Вземете сертификата “ca.crt” (след разкодиране с base64) и го запишете във файла “ca.crt”.
  • Сега създайте инстанция на метода за удостоверяване, заменяйки плейсхолдерите с получените по-рано стойности.

consul acl auth-method create 
-type "kubernetes" 
-name "auth-method-skywiz-consul-poc" 
-description "Това е метод за удостоверяване, използващ kubernetes за клъстера skywiz-app-with-consul-client-poc" 
-kubernetes-host "" 
-kubernetes-ca-cert=@ca.crt 
-kubernetes-service-account-
jwt=""

  • След това трябва да създадем правило и да го присъединим към новата роля. За тази част можете да използвате Consul UI, но ще използваме командния ред.
  • Напишете правило

### kv-custom-ns-policy.hcl
key_prefix "custom-ns/" {
 policy = "write"
}

  • Прилагане на правилото

consul acl policy create 
-name kv-custom-ns-policy 
-description "Това е примерен политика за kv на custom-ns/" 
-rules @kv-custom-ns-policy.hcl

  • Намерете идентификатора на правилото, което току-що създадохте, от изходните данни.
  • Създайте роля с новото правило.

consul acl role create 
-name "custom-ns-role" 
-description "Това е примерна роля за namespace custom-ns" 
-policy-id

  • Сега ще свържем нашата нова роля с инстанцията на метода за удостоверяване. Обърнете внимание, че флагът „селектор“ определя дали нашият входен запрос ще получава тази роля. Проверете тук за други опции на селектора: https://www.consul.io/docs/acl/auth-methods/kubernetes.html#trusted-identity-attributes

consul acl binding-rule create 
-method=auth-method-skywiz-consul-poc 
-bind-type=role 
-bind-name='custom-ns-role' 
-selector='serviceaccount.namespace=="custom-ns"'

Конфигурации накрая

Права за достъп

  • Създайте права за достъп. Трябва да дадем разрешение на Consul да валидира и идентифицира удостоверението на токена на K8s услугата.
  • Запишете следното в файл [линк]:

###skywiz-poc-consul-server_rbac.yaml
---
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
 name: review-tokens
 namespace: default
subjects:
- kind: ServiceAccount
 name: skywiz-app-with-consul-client-poc-consul-client
 namespace: default
roleRef:
 kind: ClusterRole
 name: system:auth-delegator
 apiGroup: rbac.authorization.k8s.io
---
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
 name: service-account-getter
 namespace: default
rules:
- apiGroups: [""]
 resources: ["serviceaccounts"]
 verbs: ["get"]
---
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
 name: get-service-accounts
 namespace: default
subjects:
- kind: ServiceAccount
 name: skywiz-app-with-consul-client-poc-consul-client
 namespace: default
roleRef:
 kind: ClusterRole
 name: service-account-getter
 apiGroup: rbac.authorization.k8s.io

  • Създадем права за достъп

kubectl create -f skywiz-poc-consul-server_rbac.yaml

Свързване с Consul Client

  • Както бе споменато тук., има няколко опции за свързване с daemonset, но ще преминем към следващото лесно решение:
  • Приложете следния файл [линк].

### poc-consul-client-ds-svc.yaml
apiVersion: v1
kind: Service
metadata:
 name: consul-ds-client
spec:
 selector:
   app: consul
   chart: consul-helm
   component: client
   hasDNS: "true"
   release: skywiz-app-with-consul-client-poc
 ports:
 - protocol: TCP
   port: 80
   targetPort: 8500

  • След това приложете следната вградена команда за създаване на configmap [линк]. Обърнете внимание, че се позоваваме на името на нашата услуга, заменете го при нужда.

cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: ConfigMap
metadata:
 labels:
   addonmanager.kubernetes.io/mode: EnsureExists
 name: kube-dns
 namespace: kube-system
data:
 stubDomains: |
   {"consul": ["$(kubectl get svc consul-ds-client -o jsonpath='{.spec.clusterIP}')"]}
EOF

Тестване на auth-метода

Сега нека видим магията в действие!

  • Създайте още няколко ключови папки с един и същ ключ на върха (т.е. /sample_key) и стойност по ваш избор. Създайте съответни политики и роли за новите ключови пътища. Ще направим връзките по-късно.

Въведение в Hashicorp Consul’s Kubernetes Авторизация

Пользовательски тест на пространството имен:

  • Нека създадем свое собствено пространство имен:

kubectl create namespace custom-ns

  • Нека създадем под в новото ни пространство имен. Напишете конфигурация за под.

###poc-ubuntu-custom-ns.yaml
apiVersion: v1
kind: Pod
metadata:
 name: poc-ubuntu-custom-ns
 namespace: custom-ns
spec:
 containers:
 - name: poc-ubuntu-custom-ns
   image: ubuntu
   command: ["/bin/bash", "-ec", "sleep infinity"]
 restartPolicy: Never

  • Създайте под:

kubectl create -f poc-ubuntu-custom-ns.yaml

  • След като контейнерът стартира, влезте там и инсталирайте curl.

kubectl exec poc-ubuntu-custom-ns -n custom-ns -it /bin/bash
apt-get update && apt-get install curl -y

  • Сега ще изпратим заявка за вход в Consul, използвайки метода за автентикация, който създадохме по-рано [линк].
  • За да видите въведения токен от своя акаунт на услугата:

cat /run/secrets/kubernetes.io/serviceaccount/token

  • Напишете следното в файл вътре в контейнера:

### payload.json
{
 "AuthMethod": "auth-method-test",
 "BearerToken": "<jwt_token>"
}

  • Вход!

curl 
--request POST 
--data @payload.json 
consul-ds-client.default.svc.cluster.local/v1/acl/login

  • За да изпълните горепосочените стъпки в една линия (тъй като ще изпълняваме няколко теста), можете да направите следното:

echo "{ 
"AuthMethod": "auth-method-skywiz-consul-poc", 
"BearerToken": "$(cat /run/secrets/kubernetes.io/serviceaccount/token)" 
}" 
| curl 
--request POST 
--data @- 
consul-ds-client.default.svc.cluster.local/v1/acl/login

  • Работи! Поне трябва. Сега вземете SecretID и опитайте да получите достъп до ключа/стойността, до която трябва да имаме достъп.

curl 
consul-ds-client.default.svc.cluster.local/v1/kv/custom-ns/test_key --header “X-Consul-Token: ”

  • Можете да декодирате стойността base64 и да видите, че тя съответства на стойността в custom-ns/test_key в UI. Ако сте използвали същата стойност, дадена по-горе в това ръководство, вашата кодирана стойност ще бъде IkknbSBpbiB0aGUgY3VzdG9tLW5zIGZvbGRlciEi.

Тест на акаунта на потребителската услуга:

  • Създайте потребителски ServiceAccount с помощта на следната команда [линк].

kubectl apply -f - <<EOF
apiVersion: v1
kind: ServiceAccount
metadata:
 name: custom-sa
EOF

  • Създайте нов файл конфигурация за пода. Обърнете внимание, че включих инсталацията на curl за улеснение 🙂

###poc-ubuntu-custom-sa.yaml
apiVersion: v1
kind: Pod
metadata:
 name: poc-ubuntu-custom-sa
 namespace: default
spec:
 serviceAccountName: custom-sa
 containers:
 - name: poc-ubuntu-custom-sa
   image: ubuntu
   command: ["/bin/bash","-ec"]
   args: ["apt-get update && apt-get install curl -y; sleep infinity"]
 restartPolicy: Never

  • След това стартирайте обвивка вътре в контейнера.

kubectl exec -it poc-ubuntu-custom-sa /bin/bash

  • Вход!

echo "{ 
"AuthMethod": "auth-method-skywiz-consul-poc", 
"BearerToken": "$(cat /run/secrets/kubernetes.io/serviceaccount/token)" 
}" 
| curl 
--request POST 
--data @- 
consul-ds-client.default.svc.cluster.local/v1/acl/login

  • Достъп отказан. О, забравихме да добавим ново правило за свързване с подходящи разрешения, нека го направим сега.

Повторете предишните стъпки по-горе:
а) Създайте идентична Политика за приставката "custom-sa/".
б) Създайте Role, наречете я "custom-sa-role"
в) Прикрепете Политиката към Role.

  • Създайте Rule-Binding (може да става само чрез cli / api). Обърнете внимание на друго значение за флага селектор.

consul acl binding-rule create 
-method=auth-method-skywiz-consul-poc 
-bind-type=role 
-bind-name='custom-sa-role' 
-selector='serviceaccount.name=="custom-sa"'

  • Повторете входа от контейнера "poc-ubuntu-custom-sa". Успех!
  • Проверете нашия достъп до ключовия път custom-sa/.

curl 
consul-ds-client.default.svc.cluster.local/v1/kv/custom-sa/test_key --header “X-Consul-Token: ”

  • Можете също така да се уверите, че този токен не предоставя достъп до kv в "custom-ns/". Просто повторете горепосочената команда, след като замените "custom-sa" с приставката "custom-ns".
    Достъп отказан.

Пример за оверлей:

  • Следва да се отбележи, че всички свързвания за правила ще бъдат добавени към токена с тези права.
  • Нашият контейнер "poc-ubuntu-custom-sa" се намира в пространството на имена по подразбиране — затова нека го използваме за друго свързване на правила.
  • Повторете предишните стъпки:
    а) Създайте идентична Политика за приставката на ключа "default/".
    б) Създайте Role, наречете я "default-ns-role"
    в) Прикрепете Политиката към Role.
  • Създайте Rule-Binding (може да става само чрез cli / api)

consul acl binding-rule create 
-method=auth-method-skywiz-consul-poc 
-bind-type=role 
-bind-name='default-ns-role' 
-selector='serviceaccount.namespace=="default"'

  • Върнете се към нашия контейнер "poc-ubuntu-custom-sa" и опитайте да получите достъп до пътя "default/" kv.
  • Достъп отказан.
    Можете да прегледате указаните данни за всеки токен в UI в раздела ACL > Tokens. Както виждате, на нашия текущ токен е прикрепена само една "custom-sa-role". Токенът, който в момента използваме, е генериран, когато влязохме в системата, и тогава имаше само едно свързване на правила, което отговаряше. Трябва да влезем отново в системата и да използваме нов токен.
  • Уверете се, че можете да четете както от пътищата "custom-sa/", така и от "default/" kv.
    Успех!
    Това е, защото нашият "poc-ubuntu-custom-sa" отговаря на свързванията на правила "custom-sa" и "default-ns".

Заключение

Управление на TTL за токени?

Към момента на написване на тази статия не съществува интегриран начин за определяне на TTL за токените, генерирани чрез този метод на авторизация. Това би била фантастична възможност — да се осигури безопасна автоматизация на авторизацията в Consul.

Има възможност ръчно да се създаде токен с TTL:

Надявам се в близко бъдеще да можем да контролираме как се генерират токените (за всяко правило или метод на авторизация) и да добавим TTL.

Докато е така, се предлага да използвате в логиката си крайната точка за изход.

Също така прочетете и други статии в нашия блог:

Източник: habr.com

Купете надежден хостинг за сайтове със защита от DDoS, VPS и VDS сървъри 🔥 Купете надежден хостинг за сайтове със защита от DDoS, VPS и VDS сървъри | ProHoster