使用 MYSQL_ALLOW_EMPTY_PASSWORD=yes 运行 docker mariadb/mysql 的安全风险
这是互联网上常见的 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'
[...]简单且安全,对吧?一个无 root 密码的 MariaDB 实例运行在单独的容器中,并且没有暴露其端口 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": ""
}
},
// [...]
]我们可以看到 redmine_mariadb_1 容器的 IP 地址是 172.18.0.2。
使用内部 IP 172.18.0.2,你可以访问 MySQL 服务器。
主机上的任何进程(甚至来自非特权用户)都可以无密码连接到容器,例如
mysqldump_no_password.sh
$ mysqldump -uroot -h172.18.0.2 --all-databases
// 这将显示整个 MariaDB 数据库的转储如何缓解此安全风险?
缓解相当容易,因为我们只需要为 MariaDB 实例设置 root 密码。
我推荐的最佳实践是避免重复密码。为此,在 docker-compose.yml 所在的目录中创建一个 .env 文件。
mariadb.env
MARIADB_ROOT_PASSWORD=aiPaipei6ookaemue4voo0NooC0AeH记住将密码替换为随机密码或使用此 shell 脚本自动创建:
generate_mariadb_env.sh
echo MARIADB_ROOT_PASSWORD=$(pwgen 30) > .env现在我们可以在 docker-compose.yml 中需要 MariaDB root 密码的任何地方使用 ${MARIADB_ROOT_PASSWORD},例如:
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:
- mariadbIf this post helped you, please consider buying me a coffee or donating via PayPal to support research & publishing of new posts on TechOverflow