Отправлять почту из контейнера с помощью постфиксного контейнера

Я использую приложение, размещенное в контейнере докеров. Это приложение выполняет сценарии / инструкции bash для отправки писем. Я сделал еще один контейнер, который выполняет Postfix как SMTP Relay.

Я хочу отправлять почту из контейнера моего приложения с помощью сценария bash, используя мой контейнер Postfix в качестве ретранслятора.

Я попытался подключиться по SSH из контейнера моего приложения к контейнеру Postfix. Но, похоже, это не работает.

Как я могу сделать так, чтобы сценарий, выполняемый в моем контейнере приложения, мог использовать мой ретранслятор Postfix, не разрешая при этом ничего за пределами сети докеров, или, что еще лучше, разрешать только некоторым контейнерам отправлять почту с этого ретранслятора.

РЕДАКТИРОВАТЬ 1: файлы для создания докеров

Докер приложения составляет:

version: "3.4"
volumes:
  [...]

services:
application:
    restart: always
    build: ./application
    depends_on:
    - mariadb
    container_name: application
    volumes:
      [...]
    ports:
      - "80:80"
      - "443:443"
      - "5669:5669"
    deploy:
      restart_policy:
        window: 300s
    links:
      - mariadb
    external_links:
      - smtp-server

  mariadb:
    restart: always
    image: mariadb
    command: mysqld --sql-mode=ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION
    container_name: application-mariadb
    volumes:
    [...]
    environment:
      MYSQL_RANDOM_ROOT_PASSWORD: "yes"
    deploy:
      restart_policy:
        window: 300s

Вот мой докер для моего SMTP-сервера: версия: "3.4"

services:
 postfix:
   restart: always
   build: ./postfix
   container_name: smtp-server
   deploy:
     restart_policy:
        window: 300s

person Aurelien    schedule 05.04.2018    source источник


Ответы (1)


{быстрый ответ, потому что я "повторяю" в своей работе ... и я беру 10 минут, чтобы очистить мяту, надеюсь, вам это пригодится}

Вы используете docker-compose? Не могли бы вы привести пример вашего YML-файла? (немного больше контекста)

[вы не можете подключиться по ssh к контейнеру, если у вас нет "supervisor", что я вообще не рекомендую.]

из того, что я вижу, вам нужно только создавать частные сети; Вы можете использовать это:

https://docs.docker.com/compose/networking/

чтобы скрыть все, я также рекомендую использовать балансировщик нагрузки / обратный прокси, например TRAEFIK (если у них есть доступ к порту 80 или 443 в некотором роде это ...)

поэтому вы открываете только 1/2 порта (например, 80 + 443), а все остальное защищено вашим обратным прокси

Смотрите, как я разделяю сети, поскольку вам нужны разные контейнеры.

  • bash имеет доступ к db и smtp
  • db не имеет доступа к smtp и nginx
  • nginx имеет доступ к bash
  • nginx имеет доступ к сети прокси для доступа к 80 и 443

  • ни один другой контейнер не подвергается внешнему воздействию больше, чем nginx

--

version: "3"
services:
  bash:
####### use hostname "smtp" as SMTP server
    image: bash
    depends_on:
      - db
    networks:
      - smtp_internal_network
      - internal_network
      - data_network
    volumes:
      - ../html:/var/www/html
    restart: always
  db:
    image: percona:5.7
#    ports: # for debug connections and querys
#      - 3306:3306
    volumes:
      - ../db_data:/var/lib/mysql
    environment:
      MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD}
      MYSQL_DATABASE: ${MYSQL_DATABASE}
      MYSQL_USER: ${MYSQL_USER}
      MYSQL_PASSWORD: ${MYSQL_PASSWORD}
    networks:
      - data_network
    restart: always
  smtp:
    image: mwader/postfix-relay
    environment:
      - POSTFIX_myhostname=smtp.domain.tld
    networks:
      - smtp_internal_network
    restart: always
  nginx:
    image: nginx
    volumes:
      - ../html:/var/www/html
    networks:
      - external_network
      - internal_network
  labels:
      - "traefik.backend=nginx_${COMPOSE_PROJECT_NAME}"
      - "traefik.port=80"
      - "traefik.frontend.rule=Host:${FRONTEND_RULE}"
      - "traefik.frontend.passHostHeader=true"
      - "traefik.enable=true"
      - "traefik.docker.network=traefik_proxy"
   restart: always
   depends_on:
      - db
      - bash


networks:
  external_network:
    external:
      name: traefik_proxy
  internal_network:
    driver: bridge
  smtp_internal_network:
    driver: bridge
  data_network:
    driver: bridge

Редактировать:

version: "3"
volumes:
  [...]

services:
 ####### use hostname "smtp" as SMTP server in your application
  application:
    restart: always
    build: ./application
    depends_on:
    - mariadb
    volumes:
      [...]
    ports:
      - "80:80"
      - "443:443"
      - "5669:5669"
    deploy:
      restart_policy:
        window: 300s
    networks:
      - smtp_external_network
      - data_network

  mariadb:
    restart: always
    image: mariadb
    command: mysqld --sql-mode=ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION
    networks:
      - data_network
    volumes:
    [...]
    environment:
      MYSQL_RANDOM_ROOT_PASSWORD: "yes"
    deploy:
      restart_policy:
        window: 300s

networks:
  smtp_external_network:
    external:
      name: [ReplaceForFolderParentNameOfSmtpYmlWithoutSquareBrackets]_smtp
  data_network:
    driver: bridge

--- (in your other file)

services:
 smtp:
   restart: always
   build: ./postfix
   networks:
     - smtp
   deploy:
     restart_policy:
        window: 300s

networks:
  smpt:
    driver: bridge
person nasatome    schedule 05.04.2018
comment
может быть, этот новый YML послужит вам - person nasatome; 06.04.2018
comment
Я вижу огромную проблему. Если я создам другой файл компоновки докеров, я могу получить доступ к сети между моим mariadb и контейнером приложения. Я хочу, чтобы эта сеть была ограничена моим приложением и mariadb. - person Aurelien; 10.04.2018
comment
Я не очень хорошо разбирался в проблеме, но, поскольку вы не пытаетесь ограничить приложение докера только пользователем ROOT, таким образом у вас будет доступ к ROOT, и только вы можете создавать новые экземпляры на этом сервере. (очевидно, только у вас должен быть доступ к root) //// Во-вторых, пожалуйста, не используйте какой-либо движок базы данных с докером в продакшене, запросы на iops к ядру медленнее в докере. использовать выделенный и масштабируемый облачный сервис Amazon или Google для базы данных - person nasatome; 11.04.2018
comment
Я хочу ограничить и контролировать доступ к сети для своих контейнеров. Я хочу, чтобы некоторые контейнеры взаимодействовали с другими контейнерами. Но я не хочу, чтобы это открылось. Это сделано для того, чтобы поврежденные или взломанные контейнеры не были опасны для остальных моих контейнеров. - person Aurelien; 12.04.2018
comment
Насколько я знаю, здесь я узнал о докере: сети уже изолированы друг от друга, если вы хотите повысить безопасность на случай, если злоумышленник получит контроль над процессом и, в свою очередь, обнаружит, что он находится в докере. образ и использовать некоторую уязвимость для управления хостом через ядро, лучше всего использовать пространства имен: docs.docker.com/engine/security/userns-remap Если вы найдете, как решить вашу дилемму, прокомментируйте ее, чтобы мы все узнали. - person nasatome; 12.04.2018
comment
Кажется, я нашел способ. Каждый раз, когда вы создаете службы с файлом Docker-Compose, Docker, кажется, создает сеть по умолчанию, привязанную к этому Docker Compose. Это сеть, к которой вы не можете получить доступ из другого файла Docker Compose. Я протестирую это завтра. - person Aurelien; 12.04.2018
comment
Удачи с этим тестом - person nasatome; 13.04.2018
comment
Хорошо, похоже, мои контейнеры находятся в одной сети. Но я хочу отправить почту из контейнера моего приложения, используя контейнер ретрансляции, используя bash, как это сделать? - person Aurelien; 16.04.2018