Tuesday, April 9, 2013

                         MySQL hardening script 


The MySQL database has become the world's most popular open source database because of its
consistent fast performance, high reliability and ease of use.This script gives some of the
best pracise steps to secure your database from attacks and vulnurabilities for improved
performance .
******************************************************************************
#!/bin/bash

#########################Mysqlhardeningscript################################################################Author:ratheeshvasudevan########################################
read -p "Enter mysql root password" mysqlpass

# Setting password for users 
a=`mysql -uroot -p$mysqlpass -Dmysql --execute "select User from mysql.user where length(password) = 0
or password is null;"`

if [ -z "$a" ]; then

echo "Already password is configured for all users" >> /tmp/mysqlhardening.txt

else

for i in $a

do

`mysql -uroot -p$mysqlpass -Dmysql --execute "UPDATE mysql.user SET password=PASSWORD('onmobile')  WHERE user='${i}'and length(password) = 0;"`

`mysql -uroot -p$mysqlpass -Dmysql --execute "flush privileges;"`

echo "password is set to 'onmobile'" >> /tmp/mysqlhardening.txt

done

fi
#Remove Anonymous account

`mysql -uroot -p$mysqlpass -Dmysql --execute "delete from mysql.user where user = '';"`

if [ $? -eq 0 ]; then

echo "Anonymous account is removed" >> /tmp/mysqlhardening.txt

fi
#Remove shutdown privilege for non root users 

b=`mysql -uroot -p$mysqlpass -Dmysql --execute "select user from mysql.user where Shutdown_priv = 'Y';" |grep -v "user" |grep -v "host" |grep -v "root"`

if [ -z "$b" ]; then

echo "No non admin users with shutdown privileges" >> /tmp/mysqlhardening.txt

else

for i in $b

do

mysql -uroot -p$mysqlpass -Dmysql --execute "update mysql.user set Shutdown_priv = 'N' where user='${i}';"

done

echo "removed the shutdown privileges for non admin users" >> /tmp/mysqlhardening.txt

fi

#Remove Create user privilege for non root users

c=`mysql -uroot -p$mysqlpass -Dmysql --execute "select user from mysql.user where Create_user_priv= 'Y';" |grep -v "user" |grep -v "host" |grep -v "root"`

if [ -z "$c" ]; then

echo "No non admin users with create user privileges" >> /tmp/mysqlhardening.txt

else

for i in $c

do

mysql -uroot -p$mysqlpass -Dmysql --execute "update mysql.user set Create_user_priv='N' where user='${i}';"

done
echo "Removed create user priv for non admin users" >> /tmp/mysqlhardening.txt

fi

#Remove Reload privilege for non admin users

d=`mysql -uroot -p$mysqlpass -Dmysql --execute "select user from mysql.user where Reload_priv = 'Y';" |grep -v "user" |grep -v "root"`

if [ -z "$d" ]; then

echo "No non admin users with reload privileges" >> /tmp/mysqlhardening.txt

else

for i in $d

do

mysql -uroot -p$mysqlpass -Dmysql --execute "update mysql.user set Reload_priv='N' where user='${i}';"

done

echo "Removed Reload privileges for non admin users" >> /tmp/mysqlhardening.txt

fi

#Remove GRANT Privileges for non admin users

e=`mysql -uroot -p$mysqlpass -Dmysql --execute "select user from mysql.user where Grant_priv = 'Y';" |grep -v "user" |grep -v "root"`

if [ -z "$e" ]; then

echo "No non admin users with GRANT privileges" >> /tmp/mysqlhardening.txt

else 

for i in $e

do

mysql -uroot -p$mysqlpass -Dmysql --execute "update mysql.user set Grant_priv = 'N' where user='${i}';"

done

echo "Removed non admin users with GRANT privileges" >> /tmp/mysqlhardening.txt

fi

#Old password hashing

f=`mysql -uroot -p$mysqlpass -Dmysql --execute "show variables like 'old_passwords';" |grep -v "Variable_name" |grep -v "Value" |awk -F " " '{print $2}'`

if [ `echo "$f" |grep -c "OFF"` -eq 1 ]; then

echo "Old password hashing is disabled already" >> /tmp/mysqlhardening.txt

else

mysql -uroot -p$mysqlpass -Dmysql --execute "set old_passwords = 'OFF';"

echo "old_password is set to OFF" >> /tmp/mysqlhardening.txt

fi

#Remove show database privilege for all non admin users 

g=`mysql -uroot -p$mysqlpass -Dmysql --execute "select user from mysql.user where Show_db_priv='Y';" |grep -v "user" |grep -v "root"`

if [ -z "$g" ]; then

echo "No non admin users with Show_db_priv" >> /tmp/mysqlhardening.txt

else

for i in $g 

do

mysql -uroot -p$mysqlpass -Dmysql --execute "update mysql.user set Show_db_priv='N' where user='${i}';"

done

fi

#Adding Secure auth in myql config

h=`mysql -uroot -p$mysqlpass -Dmysql --execute "show variables like 'secure_auth';" | grep -v "Variable_name" |grep -v "Value" |awk -F " " '{print $2}'`

if [ `echo "$h" |grep -c "OFF"` -eq 1 ]; then

sed -i "/^\[mysqld\]/ a\\secure_auth" /etc/my.cnf

else

echo "secure_auth is already configured in this DB" >> /tmp/mysqlhardening.txt
fi

#Removing grant tables option in mysql config 

j=`mysql -uroot -p$mysqlpass -Dmysql --execute "show variables like 'skip_grant_tables'" |grep -v "Variable_name" |grep "Value" |awk -F " " '{print $2}'`

if [ `echo "$j" |grep -c "OFF"` -eq 1 ]; then

echo "Grant tables option is already disabled in this DB" >> /tmp/mysqlhardening.txt

elif [ `echo "$j" |grep -c "ON"` -eq 1 ]; then

sed -i 's/skip_grant_tables/#skip_grant_tables/g' /etc/my.cnf

else

echo "Grant tables option is not avilable in this DB" >> /tmp/mysqlhardening.txt

fi

#Removing skip merge option from mysql

k=`mysql -uroot -p$mysqlpass -Dmysql --execute "show variables like 'have_merge_engine'" |grep -v "Variable_name" |grep "Value" |awk -F " " '{print $2}'`

if [ `echo "$k" |grep -c "DISABLED"` -eq 1 ]; then

echo "merge option is already disabled in this DB" >> /tmp/mysqlhardening.txt

elif [ `echo "$k" |grep -c "ENABLED"` -eq 1 ]; then

sed -i 's/skip_merge/#skip_merge/g' /etc/my.cnf

else

echo "merge option is not avilable in this DB" >> /tmp/mysqlhardening.txt

fi

#Removing client password from mysql config

r=`cat /etc/my.cnf |grep -A 4 "\[client\]"|grep "#password"`

cl_en=1


if [ `echo "$r" |grep -c "#password"` -eq 1 ]; then

echo "Client password is not enabled in this DB" >> /tmp/mysqlhardening.txt

else

sed -i 's/password/#password/' /etc/my.cnf

fi


#Disable interactive login

l=`cat /etc/passwd |grep mysql | awk -F ":" '{print $7}'`

if [ `echo "$l" |grep -c "/bin/bash"` -eq 1 ]; then 

usermod -s /sbin/nologin mysql

echo "interactive login is disabled for mysql user" >> /tmp/mysqlhardening.txt

else

echo "interactive login is already disabled" >> /tmp/mysqlhardening.txt

fi

#Check file system permissions 

m=`mysql -uroot -p$mysqlpass -Dmysql --execute "show variables like 'datadir';" |grep -v "variable_name" |grep -v "Value" |awk -F " " '{print $2}'`

n=`stat --format '%a' $m`

if [ `echo "$n" |grep -c "755"` -eq 1 ]; then 

echo "permission is already set for datadir" >> /tmp/mysqlhardening.txt

else 

chmod 755 $m

echo "permission is reseted for datadir" >> /tmp/mysqlhardening.txt

fi

#Configuration file permission 

o=`stat --format '%a' /etc/my.cnf`

if [ `echo "$o" |grep -c "644"` -eq 1 ]; then

echo "configuration file permission is already set for this DB" >> /tmp/mysqlhardening.txt

else

chmod 644 /etc/my.cnf

echo "Configuration file permisison is set to 644" >> /tmp/mysqlhardening.txt

fi
#Removing test database
p=`mysql -uroot -p$mysqlpass --execute "show databases;" |grep "test"`

if [ -z "$p" ]; then

echo "test database is not available in this DB" >> /tmp/mysqlhardening.txt

else

mysql -uroot -p$mysqlpass --execute "drop database test;"

echo "test database is succesfully removed" >> /tmp/mysqlhardening.txt

fi

echo "Hardening of MysqlDB is completed for this server. Please check /tmp/mysqlhardening.txt for details"