'Automate mysql_secure_installation with echo command via a shell script
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.
Solution 1:[1]
You can try to use expect, that automates interactive applications. Look at this automating mysql_secure_installation or at my modification.
Solution 2:[2]
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 3:[3]
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 4:[4]
I just did this on CentOS 6.7 with the following:
mysql_secure_installation <<EOF
y
secret
secret
y
y
y
y
EOF
Solution 5:[5]
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:[6]
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:[7]
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:[8]
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:[9]
You could try this:
echo -e "\ny\ny\nabc\nabc\ny\ny\ny\ny" | ./usr/bin/mysql_secure_installation
Solution 10:[10]
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:[11]
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:[12]
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
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow