【MySQL&docker】基于CentOS7.5 编译制作MySQL5.7.28安全加固镜像

实验背景

直接使用官方MySQL镜像,没有做进一步的安全加固,有时不符合项目中的安全规范,为了更好地控制MySQL的用户uid和目录权限,需要自己使用源码包编译制作特定版本的MySQL docker 镜像。


一、实验环境


虚拟机操作系统: CentOS7.5

docker版本:18.06.0-ce

二、创建工作目录,下载镜像制作所需软件包


# mkdir   /root/mysql5.7.28-docker

# cd   /root/mysql5.7.28-docker

# wget -O   /root/mysql5.7.28-docker/gosu     https://github.com/tianon/gosu/releases/download/1.7/gosu-amd64

# chmod  +x   /root/mysql5.7.28-docker/gosu

#  wget   http://www.sourceforge.net/projects/boost/files/boost/1.59.0/boost_1_59_0.tar.gz

#  wget   https://cdn.mysql.com//Downloads/MySQL-5.7/mysql-5.7.28.tar.gz 


# cat  Dockerfile

#############################################################################

FROM centos:centos7.5.1804

COPY mysql-5.7.28.tar.gz /opt

COPY boost_1_59_0.tar.gz /opt

RUN echo "sslverify=0" >> /etc/yum.conf && \

    yum clean all && \

    rpm --rebuilddb && \

    yum -y install gcc gcc-c++ ncurses ncurses-devel make cmake bison bison-devel openssl openssl-devel pwgen zlib zlib-devel && \

    cd /opt && \

    tar -zxf boost_1_59_0.tar.gz  && \

    mv boost_1_59_0 /usr/local/ && \

    groupadd -g 2020 mysql && \

    useradd -r -u 2020 -g  mysql -s /sbin/nologin mysql && \

    tar -zxf mysql-5.7.28.tar.gz && \

    cd mysql-5.7.28 && \

    cmake -DCMAKE_INSTALL_PREFIX=/usr/local/mysql \

          -DMYSQL_DATADIR=/var/lib/mysql \

          -DSYSCONFDIR=/etc \

          -DMYSQL_USER=mysql \

          -DMYSQL_UNIX_ADDR=/var/run/mysqld/mysql.sock \

          -DWITH_MYISAM_STORAGE_ENGINE=1 \

          -DWITH_INNOBASE_STORAGE_ENGINE=1 \

          -DWITH_ARCHIVE_STORAGE_ENGINE=1 \

          -DWITH_MEMORY_STORAGE_ENGINE=1 \

          -DWITH_READLINE=1 \

          -DENABLED_LOCAL_INFILE=1 \

          -DENABLE_DOWNLOADS=1 \

          -DWITH_PARTITION_STORAGE_ENGINE=1 \

          -DEXTRA_CHARSETS=all \

          -DDEFAULT_CHARSET=utf8 \

          -DDEFAULT_COLLATION=utf8_general_ci \

          -DWITH_DEBUG=0 \

          -DMYSQL_MAINTAINER_MODE=0 \

          -DWITH_BOOST=/usr/local/boost_1_59_0 && \

    make -j `grep processor /proc/cpuinfo | wc -l` && \

    make install && \

    yum -y remove gcc gcc-c++ ncurses-devel make cmake bison-devel openssl-devel zlib-devel && \

    yum clean all && \

    rm -rvf  /opt/* /usr/local/boost_1_59_0  /var/cache/yum/* /usr/lib/gcc && \

    mkdir -p /var/lib/mysql /etc/mysql/conf.d && \

    mkdir -p /var/run/mysqld /opt/mysql/sec_file && \

    chown -R mysql:mysql /usr/local/mysql /var/lib/mysql /etc/mysql /var/run/mysqld && \

    chmod 700 /usr/local/mysql /var/lib/mysql /etc/mysql /var/run/mysqld && \

    chmod 000 /opt/mysql/sec_file && \

    chmod 500 /usr/local/mysql/bin/* && \

    find /usr/local/mysql/lib/plugin/ -type d -exec chmod 500 {} \; && \

    find /usr/local/mysql/lib/plugin/ -type f -name "*.so" -exec chmod 400 {} \; && \

    rm -rvf /usr/local/mysql/bin/myisam* && \

    rm -rvf /usr/local/mysql/bin/mysql_config* && \

    rm -rvf /usr/local/mysql/bin/mysqlcheck && \

    rm -rvf /usr/local/mysql/bin/mysqlshow && \

    rm -rvf /usr/local/mysql/bin/mysqlslap && \

    rm -rvf /usr/local/mysql/bin/mysqlxtest && \

    rm -rvf /usr/local/mysql/mysql-test && \

    rm -rvf /usr/local/mysql/share/*.sql

COPY docker-entrypoint.sh  /

COPY my.cnf  /etc/mysql

COPY gosu /usr/local/bin/

RUN chown -R mysql:mysql /etc/mysql /docker-entrypoint.sh && \

    chmod 700 /docker-entrypoint.sh /usr/local/bin/gosu && \

    chmod 600 /etc/mysql/my.cnf

VOLUME /var/lib/mysql

ENV  PATH=/usr/local/mysql/bin:$PATH

ENV  UMASK=384

ENV  UMASK_DIR=448

ENV  MYSQL_HISTFILE=/dev/null

ENTRYPOINT ["/docker-entrypoint.sh"]

EXPOSE 3306 33060

CMD ["mysqld"]

#############################################################################


# cat docker-entrypoint.sh

############################################################

#!/bin/sh

set -e

umask 0077

if [ -z "$(ls -A /var/lib/mysql)" ]; then

    if [ -z "${MYSQL_ROOT_PASSWORD}" ]; then

        mysqld --initialize-insecure --user=mysql

    else

        mysqld --initialize-insecure --user=mysql

        cp /usr/local/mysql/support-files/mysql.server /etc/init.d/mysqld

        chmod +x /etc/init.d/mysqld

        /etc/init.d/mysqld start

        mysql -u root --skip-password -e "alter user root@'localhost' identified by \"${MYSQL_ROOT_PASSWORD}\";"

        mysql -u root  -p"${MYSQL_ROOT_PASSWORD}" -e "flush privileges;"

        /etc/init.d/mysqld stop

        rm -f /etc/init.d/mysqld

    fi

fi

exec gosu mysql "$@"

############################################################


# chmod +x   docker-entrypoint.sh

在MySQL数据目录为空、允许以非安全模式(root@'localhost'为空密码)初始化:

1. 如果MYSQL_ROOT_PASSWORD为空值,直接以非安全模式(root空密码)初始化

2. 如果MYSQL_ROOT_PASSWORD不为空值,以非安全模式初始化,然后根据MYSQL_ROOT_PASSWORD的传值,设置root@'localhost'的密码

三、用Dockerfile文件build镜像

#  docker build -f Dockerfile -t mysql:5.7.28 .

# docker images

可以看出,应该说,跟官方镜像比,体积确实大了不少!


四、用镜像起容器测试

初始化MySQL

# cat  mysql5.7.28_test.sh  

#########################################################

#!/bin/bash

mysql_ver="5.7.28"

mysql_datadir="/opt/mysqldata"

mysql_root_pwd="MySQL@123"

registry_addr=""

docker run -itd  \

  --name mysql \

  -p 3306:3306 \

  -e MYSQL_HISTFILE=/dev/null \

  -v ${mysql_datadir}:/var/lib/mysql \

  -e MYSQL_ROOT_PASSWORD="${mysql_root_pwd}" \

  mysql:${mysql_ver}

sleep 30

if ss -tan | grep -w "3306" > /dev/null 2>&1; then

  echo "Mysql init successfuly!"

else

  echo "Mysql init failed!"

fi

##########################################################

# mkdir  /opt/mysqldata

#  sh    mysql5.7.28_test.sh

#  chmod 400 /opt/mysqldata/*.pem

# docker exec -it mysql mysql -u root -p"MySQL@123"

# docker exec -it mysql mysql -u root -p"MySQL@123" -e "select user,host from mysql.user;"

开启root远程登录

# docker exec -it mysql mysql -u root -p"MySQL@123" -e "grant all privileges on *.* to root@'%' identified by 'MySQL@123' with grant option;"

 # docker exec -it mysql mysql -u root -p"MySQL@123" -e "flush privileges;"

# docker exec -it mysql mysql -u root -p"MySQL@123" -e "select user,host from mysql.user;"

# docker exec -it mysql cat /etc/passwd

# docker exec -it mysql ls -l /usr/local/mysql

五、将容器服务注册成系统服务

# docker stop mysql

# docker rm  mysql

# mkdir   /opt/mysqlconfig


# cat   /opt/mysqlconfig/my.cnf

###################################################

[mysqld]

pid-file                        = /var/run/mysqld/mysqld.pid

socket                          = /var/run/mysqld/mysql.sock

datadir                          = /var/lib/mysql

secure-file-priv                = /opt/mysql/sec_file

symbolic-links                  = 0

max_connections                  = 1000

skip_name_resolve

character-set-client-handshake  = FALSE

sql-mode                        = "ONLY_FULL_GROUP_BY,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION,STRICT_ALL_TABLES"

character-set-server            = utf8

collation-server                = utf8_general_ci

init_connect                    = "SET NAMES 'utf8'"

[mysql]

default-character-set            = utf8

[client]

default-character-set            = utf8

###################################################

# chown  -R  2020:2020   /opt/mysqlconfig

# cat /etc/systemd/system/mysqld.service

#####################################################

[Unit]

Description=MySQL Server

After=network-online.target docker.service

Requires=docker.service

[Service]

ExecStartPre=-/usr/bin/docker rm -f mysql

ExecStart=/usr/bin/docker run \

  --name mysql \

  -p 3306:3306 \

  -e UMASK=0600 \

  -e UMASK_DIR=0700 \

  -e MYSQL_HISTFILE=/dev/null \

  -v /opt/mysqldata:/var/lib/mysql \

  -v /opt/mysqlconfig/mysqld.cnf:/etc/mysql/my.cnf \

  mysql:5.7.28

ExecStop=/usr/bin/docker stop mysql

LimitNOFILE=65535

Restart=on-failure

StartLimitBurst=3

StartLimitInterval=60s

[Install]

WantedBy=multi-user.target

#####################################################


# systemctl  daemon-reload

# systemctl  start mysqld.service

# systemctl  enable mysqld.service

# systemctl  status mysqld.service

# docker exec -it mysql ps aux

# docker exec -it mysql env


六、参考  


【MySQL&docker】基于CentOS7.5 编译制作MySQL5.7.28镜像

https://www.jianshu.com/p/71fd79b69a6b


MySQL5.7 导入数据提示--secure-file-priv选项报错解决

https://blog.51cto.com/hld1992/2368512

https://www.cnblogs.com/Braveliu/p/10728162.html

MySQL UMASK或UMASK_DIR环境变量

https://www.docs4dev.com/docs/zh/mysql/5.7/reference/file-permissions.html

How to solve InnoDB: Unable to lock ./ibdata1 mysql error?

https://stackoverflow.com/questions/35978228/how-to-solve-innodb-unable-to-lock-ibdata1-mysql-error

你可能感兴趣的:(【MySQL&docker】基于CentOS7.5 编译制作MySQL5.7.28安全加固镜像)