Риск для безопасности при запуске docker mariadb/mysql с MYSQL_ALLOW_EMPTY_PASSWORD=yes

Это часть типичного docker-compose.yml, который часто встречается в интернете

docker-compose.yml
services:
  mariadb:
    image: 'mariadb:latest'
    environment:
      - MYSQL_ALLOW_EMPTY_PASSWORD=yes
      - MYSQL_DATABASE=redmine
    volumes:
      - './mariadb_data:/var/lib/mysql'
 [...]

Просто и безопасно, верно? Экземпляр MariaDB без root-пароля, работающий в отдельном контейнере и не имеющий открытого порта 3306 — поэтому только сервисы из того же docker-compose.yml могут получить к нему доступ, поскольку docker-compose помещает все эти сервисы в отдельную сеть.

Неверно.

Хотя экземпляр MariaDB недоступен из интернета, к нему может обратиться любой процесс через его внутренний IP-адрес.

Чтобы понять, что происходит, рассмотрим сети docker. В этом случае моя конфигурация docker-compose называется redmine.

docker_network_ls.txt
$ docker network ls | grep redmine
ea7ed38f469b        redmine_default           bridge              local

Это сеть, которую docker-compose создаёт без явной конфигурации сети. Давайте inspect сеть, чтобы показать хосты:

docker_network_inspect.json
[
    // [...]
        "Containers": {
            "2578fc65b4dab9f204d0a252e421dd4ddd9f41c35642d48350f4e59370581757": {
                "Name": "redmine_mariadb_1",
                "EndpointID": "1e6d81acc096a12fc740173f4e107090333c42e8a86680ac5c9886c148d578e7",
                "MacAddress": "02:42:ac:12:00:02",
                "IPv4Address": "172.18.0.2/16",
                "IPv6Address": ""
            },
            "7867f71d2a36265c34c133b70aea487b90ea68fcf30ecb42d6e7e9a376cf8e07": {
                "Name": "redmine_redmine_1",
                "EndpointID": "f5ac7b3325aa9bde12f0c625c4881f9a6fc9957da4965767563ec9a3b76c19c3",
                "MacAddress": "02:42:ac:12:00:03",
                "IPv4Address": "172.18.0.3/16",
                "IPv6Address": ""
            }
        },
    // [...]
]

Мы видим, что IP-адрес контейнера redmine_mariadb_1 — 172.18.0.2.

Используя внутренний IP 172.18.0.2, вы можете получить доступ к серверу MySQL.

Любой процесс на хосте (даже от непривилегированных пользователей) может подключиться к контейнеру без пароля, например

mysqldump_no_password.sh
$ mysqldump -uroot -h172.18.0.2 --all-databases
// This will show the dump of the entire MariaDB database

Как устранить этот риск для безопасности?

Устранение довольно простое, поскольку нам нужно только установить root-пароль для экземпляра MariaDB.

Моя рекомендуемая лучшая практика — избегать дублирования паролей. Для этого создайте файл .env в директории, где находится docker-compose.yml.

mariadb.env
MARIADB_ROOT_PASSWORD=aiPaipei6ookaemue4voo0NooC0AeH

Не забудьте заменить пароль на случайный или используйте этот скрипт для автоматического создания:

generate_mariadb_env.sh
echo MARIADB_ROOT_PASSWORD=$(pwgen 30) > .env

Теперь мы можем использовать ${MARIADB_ROOT_PASSWORD} в docker-compose.yml везде, где требуется root-пароль MariaDB, например:

docker-compose.yml
services:
  mariadb:
    image: 'mariadb:latest'
    environment:
      - MYSQL_ROOT_PASSWORD=${MARIADB_ROOT_PASSWORD}
      - MYSQL_DATABASE=redmine
    volumes:
      - './mariadb_data:/var/lib/mysql'
  redmine:
    image: 'redmine:latest'
    environment:
      - REDMINE_USERNAME=admin
      - REDMINE_PASSWORD=redmineadmin
      - REDMINE_EMAIL=ukoehler@techoverflow.net
      - REDMINE_DB_MYSQL=mariadb
      - REDMINE_DB_USERNAME=root
      - REDMINE_DB_PASSWORD=${MARIADB_ROOT_PASSWORD}
    ports:
      - '3718:3000'
    volumes:
      - './redmine_data/conf:/usr/src/redmine/conf'
      - './redmine_data/files:/usr/src/redmine/files'
      - './redmine_themes:/usr/src/redmine/public/themes'
    depends_on:
      - mariadb

Check out similar posts by category: Базы данных Docker Linux