Automate mysql_secure_installation with echo command via a shell script

MysqlLinuxShell

Mysql Problem Overview


I am trying to automate mysql_secure_installation script with automated response. My code is as follows :

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

The actual questions which i am automating are as follows:

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

But it gives me an error "Sorry you cannot use an empty password here" but in the screen i used to press the return key for the first question.

Mysql Solutions


Solution 1 - Mysql

I stumbled upon this question but decided to run the queries manually through a Bash script:

#!/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

Solution 2 - Mysql

Since mysql_secure_installation is just a Bash script, just check out the raw source code as shown here. Look for the lines that read, do_query (note that extra space I placed after do_query; need to find queries versus the function) and then you can find these commands.

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;

Note that for this example, I have the password being set to root but feel free to change that to match your setup needs. Anyway, take that simply pile of MySQL commands and save it in a file named mysql_secure_installation.sql.

With that done, just run the following command via script to secure the MySQL install:

mysql -sfu root < "mysql_secure_installation.sql"

The s silences errors and the f forces the commands to continue even if one chokes. The u relates to the username that immediately follows it which—in this case—is clearly root.

Run that in a deployment script where MySQL is installed initially without a password and you are all set to lock it down without any keyboard interaction.

PS: This script was put together to secure a MySQL installation on Ubuntu 14.04 which was installed with the export DEBIAN_FRONTEND=noninteractive set and the actual install command being set to sudo -E aptitude install -y --assume-yes -q mysql-server mysql-client. Doing that will cleanly install MySQL on Ubuntu without a password; which is nice for deployment scripts. This mysql -sfu root < "mysql_secure_installation.sql" just locks it all down in seconds after that install happens.

Solution 3 - Mysql

I just did this on CentOS 6.7 with the following:

mysql_secure_installation <<EOF

y
secret
secret
y
y
y
y
EOF

Solution 4 - Mysql

You can try to use expect, that automates interactive applications. Look at this automating mysql_secure_installation or at my modification.

Solution 5 - Mysql

Here is an automated script for a fresh MySQL 5.7 installation based on @JakeGould's answer. Works fine on CentOS 7.5.1804.

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

Solution 6 - Mysql

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

Enter current password for root (enter for none)? (I have 123 set for root)

Switch to unix_socket authentication? n

Change the root password? n

Remove anonymous users? n

Disallow root login remotely? y

Remove test database and access to it? y

Reload privilege tables now? y

Version: mysql Ver 15.1 Distrib 10.4.6-MariaDB, for osx10.14 (x86_64) using readline 5.1

Solution 7 - Mysql

It's not necessary to use expect or to fish the SQL commands out of the source code (although if you want to, the C++ file you are looking for is here: https://github.com/mysql/mysql-server/blob/7ed30a748964c009d4909cb8b4b22036ebdef239/client/mysql_secure_installation.cc)

If you are happy with the defaults in mysql_secure_installation (the most secure option is always the default) then you can use the --use-default option to skip most of the interaction. mysql_secure_installation will still ask you for a root password interactively if one is not set, so you can just script that away by setting it before calling mysql_secure_option.

Here's an example:

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

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

Solution 8 - Mysql

Works for AWS. Amazon Linux 2 AMI. Custom settings to start an instance (AWS User data):

#!/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

Solution 9 - Mysql

You could try this:

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

Solution 10 - Mysql

Just tested this on Ubuntu Bionic 18.04LTS

Step #1

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

Step #2

# 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";
# -------

Step #3

# 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";

You should be able to cut'n paste steps #2 & #3 directly into a terminal, after editing the before and after passwords from step #1.

Notes

  • If a root password has already been set step #2 will fail, so go to step #3
  • It's just a heredoc fed into the command
  • sudo is obligatory.
  • MSI has no particular meaning (it's collision avoidance; I use EOF elsewhere in the script)
  • MYPWD == NEWPWD is allowed
  • 2>/dev/null hides the warning "stty: 'standard input': Inappropriate ioctl for device"
  • You can use &>/dev/null for fully silent mode.

Solution 11 - Mysql

I am using simple command to change root password after MySql installation ,But getting the Above 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

Solution 12 - Mysql

I use following lines. Works fine for AWS Linux AMI 2018

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

Solution 13 - Mysql

  1. In Windows OS just search for 'mysql_secure_installation' application usually found in Drive:\MySQL_Install-DIR\bin\
  2. By pressing WindowKey + R just run the command 'Drive:\MySQL_Install-DIR\bin\mysql_secure_installation'

When you run this command a window will pop up that will walk you through the process of securing your MySQL installation. That's it!

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestioncucucoolView Question on Stackoverflow
Solution 1 - MysqlSleavelyView Answer on Stackoverflow
Solution 2 - MysqlGiacomo1968View Answer on Stackoverflow
Solution 3 - MysqlTSchroederView Answer on Stackoverflow
Solution 4 - MysqlVolodymyr ChumakView Answer on Stackoverflow
Solution 5 - MysqlAiden WangView Answer on Stackoverflow
Solution 6 - MysqlStan SokolovView Answer on Stackoverflow
Solution 7 - MysqlpietroreaView Answer on Stackoverflow
Solution 8 - MysqlАндрей БыченковView Answer on Stackoverflow
Solution 9 - MysqlRiccardoView Answer on Stackoverflow
Solution 10 - MysqlMartin BramwellView Answer on Stackoverflow
Solution 11 - MysqlsandeepView Answer on Stackoverflow
Solution 12 - MysqlDev BhusalView Answer on Stackoverflow
Solution 13 - MysqlJoeView Answer on Stackoverflow