Павло Щербуха

Logo

Персональна освітня сорінка

Розробка на Node.js, VUE.js, Python, IBM Integration Bus (App Connect Ent) , ORACLE PL/SQL
30 March 2023

Python Flask app with TLS on openshift

by Pavlo Shcherbukha

Постановка проблеми

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

На приклад маємо таку архітектуру компонентів:

pic-02

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

Тут стає питання, як забезпечити тільки дозволені комунікації між сервісами. Більш того, За звичай існує 2 середовища: продуктивне та тестове. І, потрібно максимально ізолювати їх між собою. І не завжди мереживні технології дозволяють це зробити. Тому, одним із швидих методів дозволити тільки очевидні комунікації між сервісами може забезпечити використання TLS протоколів з різними типами атворизації. Звичайно, це буде вимагати впровадження процесу управління ключами. Але Для тестовго і продуктового середовища можна випустити різні набори сертифікатів і тоді сервіси буде важко переплутати.

Можна побудувати для захисту таку, архітектуру для приклау.

pic-03

Користувач володіє тільк кореневим сертифікатом, що видано всьому додатку і може зати на тільки ті сервіси, що приймають сервісну авторизацію. І не запитують сертифікат клієнта. А сервіси уже комунікують сіж собою за домогою клієнтської аутентифікації. Тобто Сервер до якого звертається клієнт , запитує клієнтський сертифікат. Щоб розубратися в тому як працює 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

pic-01

показані комбінації можливих варіантів захисту.

  1. Без захисту, по чистому http. Трафіук взагалі ніяк не шифрується
  2. В цьому варіанті, трафік шифрується до самого роутера OpenShift, а далі використовується чистий http.
  3. До роутера трафік захищений одним набороб сертифікатів, а після роутера і до самого сервісу трафік шифрується уже іншим набором.
  4. Роутер просто пропускає через себе TLS трафік, і розшифровується він уже на самому сервісі.

Щоб якось перевірити це та зрозуміти як це робити розроблений приклад за лінком: tls-pyflask-srvc Запуск Python-Flask application за https. В цьому репозиторіх, як раз і використані підходи 2 та 4 з pic-01.

В проекті існує 2 приклади deployment:

В варіанті \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

Принципи та послідовність короків для генераціх сертифікатів описана за 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: