通过 shell 脚本使用 echo 命令自动化 mysql_security_install

我尝试用自动响应来自动执行 mysql _ security _ install 脚本:

echo "& y y abc abc y y y y" | ./usr/bin/mysql_secure_installation

我正在自动化的实际问题如下:

Enter current password for root (enter for none): <enter>
Set root password? [Y/n] y
New password: abc
Re-enter new password: abc
Remove anonymous users? [Y/n] y
Disallow root login remotely? [Y/n] y
Remove test database and access to it? [Y/n] y
Reload privilege tables now? [Y/n] y

但它给我一个错误“对不起,你不能使用一个空的密码在这里”,但在屏幕上,我用来按回车键的第一个问题。

77300 次浏览

您可以尝试使用自动化交互式应用程序的 期待。 看看这个 自动化 mysql _ security _ install或者我的 修改

我偶然发现了这个问题,但是决定通过 Bash 脚本手动运行查询:

#!/bin/bash


# Make sure that NOBODY can access the server without a password
mysql -e "UPDATE mysql.user SET Password = PASSWORD('CHANGEME') WHERE User = 'root'"
# Kill the anonymous users
mysql -e "DROP USER ''@'localhost'"
# Because our hostname varies we'll use some Bash magic here.
mysql -e "DROP USER ''@'$(hostname)'"
# Kill off the demo database
mysql -e "DROP DATABASE test"
# Make our changes take effect
mysql -e "FLUSH PRIVILEGES"
# Any subsequent tries to run queries this way will get access denied because lack of usr/pwd param

你可以试试这个:

echo -e "\ny\ny\nabc\nabc\ny\ny\ny\ny" | ./usr/bin/mysql_secure_installation

因为 mysql_secure_installation只是一个 Bash 脚本,所以只需要查看 如下所示的原始源代码。查找读取的行 do_query(注意我在 do_query之后放置的额外空间; 需要查找查询和函数) ,然后可以找到这些命令。

UPDATE mysql.user SET Password=PASSWORD('root') WHERE User='root';
DELETE FROM mysql.user WHERE User='';
DELETE FROM mysql.user WHERE User='root' AND Host NOT IN ('localhost', '127.0.0.1', '::1');
DROP DATABASE IF EXISTS test;
DELETE FROM mysql.db WHERE Db='test' OR Db='test\\_%';
FLUSH PRIVILEGES;

注意,对于这个示例,我将密码设置为 root,但是可以根据您的设置需要随意更改该密码。无论如何,把这些简单的 MySQL 命令保存到一个名为 mysql_secure_installation.sql的文件中。

完成之后,只需通过脚本运行以下命令来确保 MySQL 安装的安全性:

mysql -sfu root < "mysql_secure_installation.sql"

s消除错误,而 f强制命令继续执行,即使有人窒息。u与紧随其后的用户名有关,在本例中,用户名显然是 root

在一个部署脚本中运行它,在这个脚本中最初安装 MySQL 时没有密码,并且都设置为在没有任何键盘交互的情况下将其锁定。

PS: 这个脚本放在一起是为了保护 Ubuntu 14.04上的 MySQL 安装,这个安装包含 export DEBIAN_FRONTEND=noninteractive设置,实际的 install 命令设置为 sudo -E aptitude install -y --assume-yes -q mysql-server mysql-client。这样做可以干净利落地在 Ubuntu 上安装 MySQL,而不需要密码; 这对于部署脚本来说非常好。这个 mysql -sfu root < "mysql_secure_installation.sql"只是在安装完成后几秒钟内锁定它。

我刚刚在 CentOS 6.7上做了这个:

mysql_secure_installation <<EOF


y
secret
secret
y
y
y
y
EOF
  1. 在 Windows 操作系统中,只需搜索“ MySQL _ security _ install”应用程序,通常可以在 Drive: MySQL _ Install-DIR bin 中找到
  2. 按下 WindowKey + R,只需运行命令“ Drive: MySQL _ Install-DIR bin MySQL _ security _ install”

当您运行此命令时,将弹出一个窗口,它将引导您完成保护 MySQL 安装的过程。就是这样!

下面是一个基于 @ Giacomo1968的回答的新 MySQL 5.7安装的自动脚本。

yum localinstall -y https://dev.mysql.com/get/mysql57-community-release-el7-9.noarch.rpm
yum install -y mysql-community-server


# start mysql service
service mysqld start


# get Temporary root Password
root_temp_pass=$(grep 'A temporary password' /var/log/mysqld.log |tail -1 |awk '{split($0,a,": "); print a[2]}')


echo "root_temp_pass:"$root_temp_pass


# mysql_secure_installation.sql
cat > mysql_secure_installation.sql << EOF
# Make sure that NOBODY can access the server without a password
UPDATE mysql.user SET Password=PASSWORD('yourrootpass') WHERE User='root';
# Kill the anonymous users
DELETE FROM mysql.user WHERE User='';
# disallow remote login for root
DELETE FROM mysql.user WHERE User='root' AND Host NOT IN ('localhost', '127.0.0.1', '::1');
# Kill off the demo database
DROP DATABASE IF EXISTS test;
DELETE FROM mysql.db WHERE Db='test' OR Db='test\\_%';
# Make our changes take effect
FLUSH PRIVILEGES;
EOF


mysql -uroot -p"$root_temp_pass" --connect-expired-password <mysql_secure_installation.sql

我使用简单的命令改变根密码后,MySql 安装,但获得以上 error (signal 9 kill)

(FATAL: Chef::Exceptions::ChildConvergeError: Chef run process terminated by signal 9 (KILL)) Though the command works and password is changed the error is confusing.
script "change password" do
interpreter "bash"
user "root"
cwd "/tmp"
code <<-EOH
#MYSQL
root_temp_pass=$(grep 'A temporary password' /mysql/log/mysqld.log |tail -1 |awk '{split($0,a,": "); print a[2]}')


#Login as root change password
mysql -uroot -p"$root_temp_pass" -Be "ALTER USER 'root'@'localhost' IDENTIFIED BY 'Czt732ck#';" --connect-expired-password
EOH
end
sudo mysql -e "SET PASSWORD FOR root@localhost = PASSWORD('123');FLUSH PRIVILEGES;"


printf "123\n n\n n\n n\n y\n y\n y\n" | sudo mysql_secure_installation

为 root 输入当前密码(为 none 输入) ? (我为 root 设置了123个密码)

切换到 unix _ socket 身份验证? n

更改 root 密码? n

删除匿名用户

远程禁止 root 登录

删除测试数据库并访问它

现在重新加载特权表? y

版本: 用 readline 5.1分发10.4.6-MariaDB,用于 osx10.14(x86 _ 64)

刚刚在 Ubuntu Bionic 18.04 LTS 上测试过

第一步

export MYPWD="D33Ps3CR3T";
export NEWPWD="D33P3Rs3CR3T";

第二步

# First time **ever**
sudo mysql_secure_installation 2>/dev/null <<MSI


n
y
${MYPWD}
${MYPWD}
y
y
y
y


MSI


# Did it work?
mysql -u root -p${MYPWD} -e "SELECT 1+1";
# -------

第三步

# Every subsequent time
sudo mysql_secure_installation 2>/dev/null <<MSI2
${MYPWD}
n
y
${NEWPWD}
${NEWPWD}
y
y
y
y


MSI2


# Just in case (optional) ....
sudo service mysql restart


# Did it work?
mysql -u root -p${NEWPWD} -e "SELECT 1+1";


你应该能够剪切’n 粘贴步骤 # 2 & # 3直接进入终端,在编辑之前和之后的密码从步骤 # 1。

笔记

  • 如果已经设置了 root 密码,那么步骤 # 2将失败,因此转到步骤 # 3
  • 只不过是一个异教徒进入了指挥部
  • sudo是必须的。
  • MSI没有特定的含义(它是避免冲突的; 我在脚本的其他地方使用了 EOF)
  • 允许 MYPWD = = NEWPWD
  • 2>/dev/null隐藏警告 Stty: ‘ standard input’: 不适用于设备的 ioctl
  • 可以使用 &>/dev/null进行完全静音模式。

我使用以下代码行

db_root_password=Password4root
cat <<EOF | mysql_secure_installation
y
0
$db_root_password
$db_root_password
y
y
y
y
y
EOF

为 AWS 工作,Amazon Linux 2 AMI。 启动实例的自定义设置(AWS 用户数据) :

#!/bin/bash
sudo yum -y update &> /dev/null
wget https://repo.mysql.com/mysql80-community-release-el7-1.noarch.rpm &> /dev/null
sudo yum -y localinstall mysql80-community-release-el7-1.noarch.rpm
sudo yum -y install mysql-community-server &> /dev/null
sudo service mysqld start
   

# get Temporary root Password
root_temp_pass=$(sudo grep 'A temporary password' /var/log/mysqld.log |tail -1 |awk '{split($0,a,": "); print a[2]}')
echo "root_temp_pass: " $root_temp_pass
# mysql_secure_installation.sql
sudo cat > mysql_secure_installation.sql << EOF
# Make sure that NOBODY can access the server without a password
ALTER USER 'root'@'localhost' IDENTIFIED BY 'yourrootpass';
# Kill the anonymous users
DELETE FROM mysql.user WHERE User='';
# disallow remote login for root
DELETE FROM mysql.user WHERE User='root' AND Host NOT IN ('localhost', '127.0.0.1', '::1');
# Kill off the demo database
DROP DATABASE IF EXISTS test;
DELETE FROM mysql.db WHERE Db='test' OR Db='test\\_%';
# Make our changes take effect
FLUSH PRIVILEGES;
EOF
        

sudo mysql -uroot -p"$root_temp_pass" --connect-expired-password <mysql_secure_installation.sql
sudo systemctl enable mysql

没有必要使用 expect或者从源代码中找出 SQL 命令(尽管如果您愿意,您正在寻找的 C + + 文件在这里: https://github.com/mysql/mysql-server/blob/7ed30a748964c009d4909cb8b4b22036ebdef239/client/mysql_secure_installation.cc)

如果您对 mysql_secure_installation中的默认设置感到满意(最安全的选项总是默认设置) ,那么可以使用 --use-default选项跳过大部分交互。如果没有设置 root 密码,mysql_secure_installation仍然会以交互方式要求您输入根密码,所以您可以在调用 mysql_secure_option之前通过设置根密码来编写脚本。

这里有一个例子:

mysql -u root <<EOF
SET PASSWORD FOR root@localhost = '${ROOT_PASSWORD}';
FLUSH PRIVILEGES;
EOF


mysql_secure_installation -u root --password="${ROOT_PASSWORD}" --use-default

我也有同样的问题。 将 echo 命令替换为使用 -e\n似乎已经修复了它。

echo -e "\ny\ny\nabc\nabc\ny\ny\ny\ny\n" | ./usr/bin/mysql_secure_installation

最受欢迎的解决方案是一个小技巧,它是版本、旋转和操作系统特有的。不幸的是,RHEL9附带的脚本不支持优雅的解决方案(使用—— use-default)。

这里有一个比较兼容的方法,可以从附带的脚本中提取正确的命令:

grep 'do_query ' /usr/bin/mariadb-secure-installation | \
sed -e 's/ *do_query \"//' -e 's/\"$//' \
-e "s/\$esc_pass/$db_admin_pass/" \
-e 's/([^;])$/\\1;/' | \
grep -v 'show create' | \
mysql --user=$db_admin_user

前2个 sed 命令从每个 SQL 命令中去掉 do _ query 调用。 第二行设置新的 root 密码。 第三行为任何未终止的 SQL 命令添加了一个尾部分号; 这在 RHEL9附带的脚本中是不成立的

该命令假定您提供了变量 $db _ admin _ user 和 $db _ admin _ pass

代码是从我的木偶清单中提取出来的,因此命令引用可能会因您使用它的方式而有所不同。

Mysql 命令需要 root 特权(它应该从您的自动化引擎继承这些特权)

echo -e "${MARIADB_ROOT_PASSWORD}\nY\nn\nY\nn\nY\nY\n" | ./usr/bin/mysql_secure_installation

确实为我工作,在我的 Mariadb 码头集装箱里。没有这个调用,我不能让简单的事情,如 /etc/init.d/mariadb status运行。