INTEGRITY Документация

MongoDB SSH

Вы можете создавать правила Zero Trust для защиты подключений к развёртываниям MongoDB с помощью Cloudflare Access и Cloudflare Tunnel. Для работы Cloudflare Tunnel требуется лёгкий демон, cloudflared, работающий вместе с развёртыванием, а также на стороне клиента.

В этом руководстве клиент, на котором запущен cloudflared подключается по SSH к развертыванию MongoDB, работающему в Kubernetes. Этот пример развертывания построен таким образом, чтобы подключать Compass к экземпляру MongoDB. Развёртывание MongoDB в Kubernetes запускает как службу базы данных MongoDB, так и cloudflared как ingress-службу, которая работает подобно промежуточному узлу (jump host).

В этом руководстве рассматривается, как:

Время выполнения:

50 минут


Настройте Cloudflare Access

Вы можете создать правило в Cloudflare Access, чтобы контролировать, кто может подключаться к вашему развёртыванию MongoDB. Правила Cloudflare Access строятся на основе имени хоста: хотя это развёртывание будет доступно по SSH, в Cloudflare оно будет представлено как имя хоста. Например, если у вас есть веб-сайт app.com в вашем аккаунте Cloudflare, вы можете создать правило для защиты mongodb.app.com.

  1. В Панель управления Cloudflare, перейдите в Zero Trust > Контроль доступа > Приложения.

  2. Выберите Создать новое приложение.

  3. Выберите Самостоятельный хостинг и конфиденциальность.

  4. Выберите Добавьте общедоступное имя хоста и введите поддомен, через который пользователи будут подключаться к вашему развёртыванию (например, mongodb.app.com).

  5. Добавить Политики доступа чтобы управлять тем, кто может обращаться к развёртыванию. Вы можете создать политику, которая разрешает подключение любому пользователю в вашей организации, или более детализированные политики на основе таких сигналов, как группы поставщика идентификации, многофакторный метод, или страна.

  6. Выполните оставшиеся шаги по созданию самостоятельно размещённого приложения чтобы опубликовать приложение.

Настройте развёртывание Kubernetes

Чтобы обеспечить доступ по SSH, развёртывание Kubernetes должно управлять как автономным сервисом MongoDB, так и сервисом SSH-прокси. Приведённая ниже конфигурация развернёт 1 реплику сервиса базы данных, доступную на порту 27017, а также SSH-прокси, доступный на порту 22.

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

apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: mongodb-standalone
  namespace: mongodb
spec:
  serviceName: database
  replicas: 1
  selector:
    matchLabels:
      app: database
  template:
    metadata:
      labels:
        app: database
        selector: mongodb-standalone
    spec:
      containers:
        - name: mongodb-standalone
          image: mongo
          command: ["mongod"]
          args: ["--config=/config/mongod.conf"]
          ports:
            - containerPort: 27017
              protocol: TCP
              name: mongod
          volumeMounts:
            - name: mongodb-conf
              mountPath: /config
              readOnly: true
            - name: mongodb-data
              mountPath: /data/db
            - name: tls
              mountPath: /etc/tls
            - name: mongodb-socket
              mountPath: /socket
        - name: ssh-proxy
          image: ubuntu:20.04
          command: ["/scripts/entrypoint.sh"]
          ports:
            - containerPort: 22
              protocol: TCP
              name: ssh-port
          volumeMounts:
            - name: mongodb-socket
              mountPath: /socket
            - name: scripts
              mountPath: /scripts
              readOnly: true
            - name: ssh-authorized-keys
              mountPath: /config/ssh
              readOnly: true
          resources:
            requests:
              cpu: 20m
              memory: 32Mi
      volumes:
        - name: mongodb-socket
          emptyDir: {}
        - name: mongodb-conf
          configMap:
            name: mongodb-standalone
            items:
              - key: mongod.conf
                path: mongod.conf
        - name: tls
          secret:
            secretName: tls
        - name: mongodb-data
          persistentVolumeClaim:
            claimName: mongodb-standalone
        - name: scripts
          configMap:
            name: scripts
            items:
              - key: entrypoint.sh
                path: entrypoint.sh
                mode: 0744
        - name: ssh-authorized-keys
          configMap:
            name: ssh-proxy-config
            items:
              - key: authorized_keys
                path: authorized_keys
                mode: 0400

В соответствующем описании службы также нужно указать порты и целевые порты для контейнеров (в данном случае для службы базы данных и службы SSH-прокси).

Определение службы

apiVersion: v1
kind: Service
metadata:
  name: database
  namespace: mongodb
  labels:
    app: database
spec:
  clusterIP: None
  selector:
    app: database
  ports:
    - protocol: TCP
      port: 27017
      targetPort: 27017
---
apiVersion: v1
kind: Service
metadata:
  name: ssh-proxy
  namespace: mongodb
  labels:
    app: database
spec:
  selector:
    app: database
  ports:
    - protocol: TCP
      port: 22
      targetPort: 22

Под MongoDB и SSH jump host будут совместно использовать Unix-сокет через пустой том emptyDir. entrypoint.sh файл, запускаемый на jump host (пример ниже), запустит OpenSSH-сервер.

#!/bin/sh
export TZ=America/Chicago
ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
apt-get update -y && apt-get install -y openssh-server
mkdir /root/.ssh
cp /config/ssh/authorized_keys /root/.ssh/authorized_keys
chmod 400 /root/.ssh/authorized_keys
service ssh start
while true;
do sleep 30;
done;

Настройте Cloudflare Tunnel

Далее вы можете использовать cloudflared чтобы подключиться к периферии Cloudflare с помощью Cloudflare Tunnel. Начните с скачивание и установка демон Cloudflare Tunnel, cloudflared.

После установки выполните следующую команду, чтобы пройти аутентификацию для экземпляра cloudflared в ваш аккаунт Cloudflare.

cloudflared login

Команда откроет окно браузера и предложит войти с помощью вашего аккаунта Cloudflare. Выберите веб-сайт, который вы добавили в свой аккаунт.

После выбора одного из сайтов аккаунта Cloudflare загрузит файл сертификата с именем cert.pem чтобы аутентифицировать этот экземпляр cloudflared. cert.pem файл использует сертификат для аутентификации вашего экземпляра cloudflared и включает ключ API для вашего аккаунта, позволяющий выполнять такие действия, как изменение записей DNS.

Теперь можно использовать cloudflared чтобы управлять подключениями Cloudflare Tunnel в своём аккаунте Cloudflare.

Скачать сертификат

Создайте Tunnel

Теперь вы можете создать Tunnel который подключит cloudflared к периферийной сети Cloudflare. Параметры этого туннеля вы настроите на следующем шаге.

Выполните следующую команду, чтобы создать туннель. Вы можете заменить mongodb с любым именем на ваш выбор. Для этой команды требуется cert.pem файл.

cloudflared tunnel create mongodb

Cloudflare создаст Tunnel с этим именем и сгенерирует для него ID и файл учетных данных.

Новый туннель

Удалите cert.pem файл

Файл учётных данных отделён от cert.pem файл. В отличие от cert.pem файл: файл учётных данных состоит из токена, который аутентифицирует только Named Tunnel, который вы только что создали. В формате JSON, файл не может вносить изменения в ваш аккаунт Cloudflare или создавать дополнительные Tunnel.

Если вы закончили создавать туннели, вы можете удалить cert.pem файл, оставьте только файл учётных данных и продолжайте управлять записями DNS напрямую через панель управления Cloudflare или API. Дополнительную информацию о различиях в функциях этих двух файлов см. в списке полезные термины.

Сохраните JSON файл как Kubernetes secret.

Настройте Cloudflare Tunnel

В предыдущих шагах использовался cloudflared чтобы создать файл учётных данных для вашего аккаунта Cloudflare. При запуске в качестве службы вместе с развёртыванием MongoDB Kubernetes вам потребуется использовать образ Docker версии cloudflared. Cloudflare выполняет доступен официальный образ в DockerHub.

Приведённая ниже конфигурация запустит одну реплику cloudflared как точку входа (ingress) наряду со службами MongoDB и SSH-прокси. cloudflared будет проксировать трафик к службе SSH-прокси. cloudflared экземпляр будет работать как отдельный deployment в другом пространстве имён и, если это разрешено сетевой политикой, сможет принимать входящий трафик к любому сервису в узле Kubernetes.

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

apiVersion: apps/v1
kind: Deployment
metadata:
  name: dashboard-tunnel
  namespace: argotunnel
  labels:
    app: dashboard-tunnel
spec:
  replicas: 1
  selector:
    matchLabels:
      app: dashboard-tunnel
  template:
    metadata:
      labels:
        app: dashboard-tunnel
    spec:
      containers:
        - name: dashboard-tunnel
          # Image from https://hub.docker.com/r/cloudflare/cloudflared
          image: cloudflare/cloudflared:2020.11.11
          command: ["cloudflared", "tunnel"]
          args: ["--config", "/etc/tunnel/config.yaml", "run"]
          ports:
            - containerPort: 5000
          livenessProbe:
            tcpSocket:
              port: 5000
            initialDelaySeconds: 60
            periodSeconds: 60
          volumeMounts:
            - name: dashboard-tunnel-config
              mountPath: /etc/tunnel
            - name: tunnel-credentials
              mountPath: /etc/credentials
      volumes:
        - name: dashboard-tunnel-config
          configMap:
            name: dashboard-tunnel-config
        - name: tunnel-credentials
          secret:
            secretName: tunnel-credentials
---
apiVersion: v1
kind: ConfigMap
metadata:
  name: dashboard-tunnel-config
  namespace: argotunnel
data:
  config.yaml: |
    tunnel: 9a00ef26-4997-4de2-83db-631efc74245c
    credentials-file: /etc/credentials/k8s-dashboard.json
    metrics: :5000
    protocol: http2
    no-autoupdate: true
    ingress:
    - hostname: mongodb.widgetcorp.tech
      originRequest:
        bastionMode: true
    - service: http_status:404

Подключитесь с клиента

После развёртывания вы можете выполнить cloudflared на стороне клиента для подключения к развёртыванию MongoDB. Добавьте следующие строки в файл конфигурации SSH, заменив примеры на своё имя хоста и данные. --destination значение должно совпадать с URL-адресом службы SSH Proxy, настроенной ранее.

Host mongodb
  ProxyCommand /usr/local/bin/cloudflared access ssh --hostname mongodb.widgetcorp.tech --destination ssh-proxy.mongodb.svc.cluster.local:22
  LocalForward 27000 /socket/mongodb-27017.sock
  User root
  IdentityFile /Users/username/.ssh/id_rsa

Это разовое действие. При следующей попытке установить SSH-подключение к развёртыванию cloudflared откроет окно браузера и предложит вам пройти аутентификацию. После успешной аутентификации вы будете подключены, если у вас есть действительная сессия. После установления туннеля все запросы к localhost:27000 на вашем компьютере будет перенаправлен на /socket/mongodb-27017.sock на контейнере SSH-прокси.

После этого можно настроить MongoDB Compass для подключения к localhost:27000.