Персональна освітня сорінка
by Pavlo Shcherbukha
При розробці сучасних багатосервісних систем частно виникає необхідність захисту даних на трансопортному рівні. Тому це було першопричиною для того щоб розібратися в цьому, а потім написати цей блог. А в процесі вивчення теми виникли додаткові аргументи в цій сфері.
На приклад маємо таку архітектуру компонентів:

Синіми та чорними лініями показана дозволена взаємодія клієнта (сині) та приладних сервісів (чорні). Червона лінія показує заборонену взаємодію. Може виникнути питання, чому ця дія заборонена. На компоненті RestApi скоріше за все немає аутентифікації користувача. Більш того, backend сервіси можуть організовувати с RestApi сервісом взаємодію, по специфічному шаблону взаємодії типу: webpooling чи webhook - для того щоб не перевантажити сервіс, чи отримати дані послідовно, порціями, а потім користувачу віддати вже все. При чому, customer, це не завжди вреднючий користувач. Просто він користується такми фронтом, де програміст зробив “покращення”, тому що так швидше.
Тут стає питання, як забезпечити тільки дозволені комунікації між сервісами. Більш того, За звичай існує 2 середовища: продуктивне та тестове. І, потрібно максимально ізолювати їх між собою. І не завжди мереживні технології дозволяють це зробити. Тому, одним із швидих методів дозволити тільки очевидні комунікації між сервісами може забезпечити використання TLS протоколів з різними типами атворизації. Звичайно, це буде вимагати впровадження процесу управління ключами. Але Для тестовго і продуктового середовища можна випустити різні набори сертифікатів і тоді сервіси буде важко переплутати.
Можна побудувати для захисту таку, архітектуру для приклау.

Користувач володіє тільк кореневим сертифікатом, що видано всьому додатку і може зати на тільки ті сервіси, що приймають сервісну авторизацію. І не запитують сертифікат клієнта. А сервіси уже комунікують сіж собою за домогою клієнтської аутентифікації. Тобто Сервер до якого звертається клієнт , запитує клієнтський сертифікат. Щоб розубратися в тому як працює TLS За лінком: tls-self-sign-certs Набрі кроків для генерації самопідписних TLS сертифікатів описаний простий набір кроків як розробнику швидко строрити набір tls сертифікатів та демка на Node.js express як перевірити їх працездатність. Тут можна легко згенерувати набір сертифікатів для серверно та клієнтської аутентифікації. Також наведені приклади на Node.JS для перевірки робти різних варіантів аутентифікацій, використовуючи тільк що згенеровані ключі та сертифікати. Ці кроки уже кілька разів використовував, коли виникала необхідність змоделювати роботу інших сервісів. Виявилося дуже зручно. Звичайно, наведена архітектура не едний можливий шлях. Це вже прилінкувалося у зв’язку з вивченнм, як використати TLS з Python-Flask додатками. Основним завданням у мене було розібратися, як запустити Python flask сервіси за tls протоколом на Openshift. Найбльш коротко і лаконічно описано про можливості використання транспортного захисту в роутерах openshift за лінком Secure your-microservices with RedHat OpenShft Routes. Ось pic-01

показані комбінації можливих варіантів захисту.
Щоб якось перевірити це та зрозуміти як це робити розроблений приклад за лінком: tls-pyflask-srvc Запуск Python-Flask application за https. В цьому репозиторіх, як раз і використані підходи 2 та 4 з pic-01.
В проекті існує 2 приклади deployment:
\openshift\ubi8_docker_deployment TLS доходить до Flask application
\openshift-tls-edge\ubi8_docker_deployment TSL доходить тількт до route openshift, а далі трафік уже не захищений.
В варіанті \openshift\ubi8_docker_deployment python запускається за gunicorn, тому ніяких змін в python код вносити не потрібно. Потрібно зробити 2 кроки, а саме:
Ось цитата з Dockerfile, для Redhat Ubi8-python базового образу
# Put self signed CA into trust store
RUN cp /tmp/src/sh_app/tlscert/ca-crt.pem /usr/share/pki/ca-trust-source/anchors/
RUN ls /usr/share/pki/ca-trust-source/anchors/
RUN update-ca-trust
spec:
containers:
- env:
- name: GUNICORN_CMD_ARGS
value: --workers=1 --worker-connections=2000 --bind=0.0.0.0:8080 --access-logfile=---keyfile /opt/app-root/src/sh_app/tlscert/server-key.pem --certfile /opt/app-root/src/sh_app/tlscert/server-crt.pem
Ну і далі в програмному коді нічго міняти не портібно в Deploymentconfig також ні, окрім роутера. В роутері додається додатковий ключ tls із значеннмя termination: passthrough
spec:
host: "${HOSTNAME}"
port:
targetPort: $
# новий розділ start
tls:
termination: passthrough
# новий розділ stop
to:
kind: "Service"
name: ${APP_SERVICE_NAME}
weight: null
В роутері з`являється ноий блок tls, куди вносяться сертифікати та ключі
spec:
host: "${HOSTNAME}"
port:
targetPort: $
# новий розділ start
tls:
termination: edge
certificate: |
-----BEGIN CERTIFICATE-----
#
-----END CERTIFICATE-----
key: |
-----BEGIN PRIVATE KEY-----
-----END PRIVATE KEY-----
caCertificate: |
-----BEGIN CERTIFICATE-----
-----END CERTIFICATE-----
insecureEdgeTerminationPolicy: Allow
wildcardPolicy: None
# новий розділ stop
to:
kind: "Service"
Принципи та послідовність короків для генераціх сертифікатів описана за tls-self-sign-certs Набрі кроків для генерації самопідписних TLS сертифікатів.
Для варіанту \openshift-tls-edge\ubi8_docker_deployment в сертифікатах в реквізиті CN вказував маску URL в ca.cnf та в server.cnf
CN = *.apps.sandbox-myowndomain.openshiftapps.com
Використовується серверна аутентифікація. Тому у відповідності з посиланням- сертифікати генеруються в 4 кроки. 1
tags: