diff options
author | Anel Husakovic <anel@mariadb.org> | 2021-06-27 12:19:13 +0200 |
---|---|---|
committer | Anel Husakovic <anel@mariadb.org> | 2021-07-07 07:15:11 +0200 |
commit | 2c2cfabe257821d9d6aafd374a5ba92aac619347 (patch) | |
tree | 05a2b5e5d3a7361a0140306f560abe6cc030327b | |
parent | 3c34332fb862424aef814b9960b27d8b225da2ff (diff) | |
download | mariadb-git-st-10.4-anel-mysql-secureinstall.tar.gz |
- Add mtr test case and remove errors for `stty`
- Use interrupt function for unsuccessful read
- Remove records of `test*` from `mysql.db` in order to create function
`check_removed_test_db` - thanks daniel@mariadb.org
- Remove not needed sentence
- Adding check_removed_test_db
- Adding check for hostname with quoted parameters
- Add flag for failures
- Allow passing parameters through command line interface
- mtr result still has some files not removed - review
Reviewed by: daniel@mariadb.org
-rw-r--r-- | mysql-test/main/mysql_secure_installation.result | 59 | ||||
-rw-r--r-- | mysql-test/main/mysql_secure_installation.test | 42 | ||||
-rw-r--r-- | scripts/mysql_secure_installation.sh | 102 |
3 files changed, 135 insertions, 68 deletions
diff --git a/mysql-test/main/mysql_secure_installation.result b/mysql-test/main/mysql_secure_installation.result index dcf0e084974..9811c09c931 100644 --- a/mysql-test/main/mysql_secure_installation.result +++ b/mysql-test/main/mysql_secure_installation.result @@ -1,10 +1,20 @@ -SELECT user,host FROM mysql.global_priv ORDER BY user,host; -user host -mariadb.sys localhost -root 127.0.0.1 -root ::1 -root anel -root localhost +CREATE USER foobar@localhost IDENTIFIED BY "bar"; +GRANT ALL PRIVILEGES ON *.* TO foobar@localhost; +SELECT user FROM mysql.global_priv ORDER BY user; +user +foobar +mariadb.sys +root +root +root +root +SHOW DATABASES; +Database +information_schema +mtr +mysql +performance_schema +test NOTE: RUNNING ALL PARTS OF THIS SCRIPT IS RECOMMENDED FOR ALL MariaDB SERVERS IN PRODUCTION USE! PLEASE READ EACH STEP CAREFULLY! @@ -14,18 +24,13 @@ password for a privileged user. If you've just installed MariaDB, and haven't set a privileged password yet, you should just press enter here. For which user do you want to specify a password (press enter for USERNAME): -Enter current password for user rootnnUSERNAMEnYnsecretnsecretnYnnn (enter for none): -Only privileged user can make changes to mysql DB. -For which user do you want to specify a password (press enter for USERNAME): -.my.output.47113 -1 +Enter current password for user foobar (enter for none): OK, successfully used password, moving on... -User: USERNAME and 1 -You already have your user account protected (unix_socket auth and password set, or password impossible to use), so you can safely answer 'n'. - -Set the user: USERNAME password? [Y/n] ... skipping. +Set user: foobar password? [Y/n] New password: +Re-enter new password: +Password updated successfully! By default, a MariaDB installation has an anonymous user, allowing anyone to log into MariaDB without having to have a user account created for @@ -39,6 +44,7 @@ By default, MariaDB comes with a database named 'test' that anyone can access. This is also intended only for testing, and should be removed before moving into a production environment. + - Checking the test databases... Remove test database and access to it? [Y/n] - Dropping test database... ... Success! - Removing privileges on test database... @@ -55,17 +61,10 @@ All done! If you've completed all of the above steps, your MariaDB installation should now be secure. Thanks for using MariaDB! -SHOW DATABASES; -Database -information_schema -mtr -mysql -performance_schema -test -SELECT user,host FROM mysql.global_priv ORDER BY user,host; -user host -mariadb.sys localhost -root 127.0.0.1 -root ::1 -root anel -root localhost +SELECT user FROM mysql.global_priv ORDER BY user; +user +foobar +mariadb.sys +root +# Kill the server +# restart diff --git a/mysql-test/main/mysql_secure_installation.test b/mysql-test/main/mysql_secure_installation.test index f16a14eeb1e..f15b3bc0e55 100644 --- a/mysql-test/main/mysql_secure_installation.test +++ b/mysql-test/main/mysql_secure_installation.test @@ -1,15 +1,43 @@ --source include/not_windows.inc -SELECT user,host FROM mysql.global_priv ORDER BY user,host; +CREATE USER foobar@localhost IDENTIFIED BY "bar"; +GRANT ALL PRIVILEGES ON *.* TO foobar@localhost; +SELECT user FROM mysql.global_priv ORDER BY user; +SHOW DATABASES; ---replace_result $USER USERNAME # Creating a temporary text file. ---write_file $MYSQL_TMP_DIR/mariadb-secure-installation.txt -root\n\nanel\nY\nsecret\nsecret\nY\n\n\n +--write_file $MYSQLTEST_VARDIR/tmp/mariadb_secure_installation.txt +foobar +bar +Y +secret +secret +Y + + EOF ---exec $MYSQL_SECURE_INSTALLATION < $MYSQL_TMP_DIR/mariadb-secure-installation.txt -SHOW DATABASES; -SELECT user,host FROM mysql.global_priv ORDER BY user,host; +--replace_result $USER USERNAME +--exec $MYSQL_SECURE_INSTALLATION -S $MASTER_MYSOCK< $MYSQLTEST_VARDIR/tmp/mariadb_secure_installation.txt + +SELECT user FROM mysql.global_priv ORDER BY user; + +--remove_file $MYSQLTEST_VARDIR/tmp/mariadb_secure_installation.txt +--let MYSQLD_DATADIR= `select @@datadir` +--source include/kill_mysqld.inc +# No need to clean anything since the datadir will be removed +--rmdir $MYSQLD_DATADIR + +perl; +use lib "lib"; +use My::Handles { suppress_init_messages => 1 }; +use My::File::Path; +my $install_db_dir = ($ENV{MTR_PARALLEL} == 1) ? + "$ENV{'MYSQLTEST_VARDIR'}/install.db" : + "$ENV{'MYSQLTEST_VARDIR'}/../install.db"; +copytree($install_db_dir, $ENV{'MYSQLD_DATADIR'}); +EOF +--let $restart_parameters= $old_restart_parameters +--source include/start_mysqld.inc diff --git a/scripts/mysql_secure_installation.sh b/scripts/mysql_secure_installation.sh index e224def9586..11054ab079a 100644 --- a/scripts/mysql_secure_installation.sh +++ b/scripts/mysql_secure_installation.sh @@ -284,7 +284,7 @@ get_user_and_password() { while [ $status_priv_user -ne 0 ]; do if test -z "$user"; then echo $echo_n "For which user do you want to specify a password (press enter for $USER): $echo_c" - read user + read user || interrupt echo if [ "x$user" = "x" ]; then emptyuser=1 @@ -294,10 +294,10 @@ get_user_and_password() { fi fi if [ -z "$password" ] && [ "$emptyuser" -eq 0 ]; then - stty -echo + stty -echo 2>/dev/null # If the empty user it means we are connecting with unix_socket else need password echo $echo_n "Enter current password for user $user (enter for none): $echo_c" - read password + read password || interrupt echo stty echo fi @@ -325,18 +325,18 @@ get_user_and_password() { else password_set=0 fi - read -r show_create < "$output" + read -r show_create < "$output" || interrupt echo "OK, successfully used password, moving on..." echo } set_user_password() { - stty -echo + stty -echo 2>/dev/null echo $echo_n "New password: $echo_c" - read password1 + read password1 || interrupt echo echo $echo_n "Re-enter new password: $echo_c" - read password + read password || interrupt echo stty echo @@ -351,7 +351,6 @@ set_user_password() { echo return 1 fi - esc_pass=$(basic_single_escape "$password1") do_query "SET PASSWORD = PASSWORD('$esc_pass')" if [ $? -eq 0 ]; then @@ -360,6 +359,7 @@ set_user_password() { echo "Password update failed!" clean_and_exit fi + args="$args --password=$password" make_config return 0 @@ -370,11 +370,10 @@ remove_anonymous_users() { DROP USER /*M!100103 IF EXISTS */ ''@localhost; /*M!100203 EXECUTE IMMEDIATE CONCAT('DROP USER IF EXISTS \'\'@', @@hostname) */; EOANON - if [ $? -eq 0 ]; then echo " ... Success!" else - echo " ... Failed!" + echo " ... Failed to remove anonymous users!" clean_and_exit fi @@ -400,17 +399,36 @@ EOREMOTEROOT if [ $? -eq 0 ]; then echo " ... Success!" else - echo " ... Failed!" + echo " ... Failed to remove remote root!" + fi +} + +check_test_database() { + echo " - Checking the test databases..." + do_query << EOCHECKTESTDB +SELECT schema_name FROM information_schema.schemata +WHERE schema_name LIKE 'test'; +EOCHECKTESTDB + if [ $? -eq 0 ]; then + if grep -q "test" "$output"; then + return 1 + else + return 0 + fi + else + echo " ... Failed to check test database! Not critical, keep moving..." fi } remove_test_database() { echo " - Dropping test database..." - do_query "DROP DATABASE IF EXISTS test;" + do_query <<-EODROPTESTDB +DROP DATABASE IF EXISTS test; +EODROPTESTDB if [ $? -eq 0 ]; then echo " ... Success!" else - echo " ... Failed! Not critical, keep moving..." + echo " ... Failed to remove test database! Not critical, keep moving..." fi echo " - Removing privileges on test database..." @@ -418,14 +436,18 @@ remove_test_database() { DELIMITER && CREATE OR REPLACE PROCEDURE mysql.secure_test_users() BEGIN -SELECT GROUP_CONCAT(DISTINCT CONCAT(QUOTE(user),'@',QUOTE(host))) INTO @users FROM mysql.db WHERE Db='test' AND user!=''; +SELECT GROUP_CONCAT(DISTINCT CONCAT(QUOTE(user),'@',QUOTE(host))) INTO @users FROM mysql.db JOIN mysql.global_priv USING (User,Host) WHERE Db='test'; IF @users IS NOT NULL THEN EXECUTE IMMEDIATE CONCAT('REVOKE ALL ON test.* FROM ', @users); END IF; -SELECT GROUP_CONCAT(DISTINCT CONCAT(QUOTE(user),'@',QUOTE(host))) INTO @users FROM mysql.db WHERE Db='test\\_%' AND user!=''; +SELECT GROUP_CONCAT(DISTINCT CONCAT(QUOTE(user),'@',QUOTE(host))) INTO @users FROM mysql.db JOIN mysql.global_priv USING (User,Host) WHERE Db='test\\_%'; IF @users IS NOT NULL THEN EXECUTE IMMEDIATE CONCAT('REVOKE ALL ON \`test\\_%\`.* FROM ', @users); END IF; +DELETE FROM mysql.db WHERE User='' AND Db IN ('test', 'test\\_%'); +IF ROW_COUNT() THEN + FLUSH PRIVILEGES; +END IF; END; && DELIMITER ; @@ -436,7 +458,7 @@ EOTEST if [ $? -eq 0 ]; then echo " ... Success!" else - echo " ... Failed! Not critical, keep moving..." + echo " ... Failed to remove privileges on test database! Not critical, keep moving..." fi return 0 @@ -482,14 +504,23 @@ if [ $user = root ] && [ $unix_socket_auth -ne 1 ]; then echo "Changing the root username obfuscates administrative users and" echo "helps prevent targeted attacks." echo - echo "If you change the root username you must provide a password for" - echo "the user." - echo echo $echo_n "Change root username to what username? (blank for no change) $echo_c" - read reply + read reply || interrupt if [ -n "$reply" ]; then - user=$reply - do_query "EXECUTE IMMEDIATE CONCAT('RENAME USER ', CURRENT_USER(), ' TO $user')" + # Check user has @ in the name + case "$reply" in + *@*) + user=${reply%@*} + host=${reply#*@} + ;; + *) + user=${reply} + host="localhost" + ;; + esac + + do_query "EXECUTE IMMEDIATE CONCAT('RENAME USER ', CURRENT_USER(), ' TO \'$user\'@\'$host\'')" + args="$args --user=$user --host=$host" make_config fi fi @@ -505,7 +536,7 @@ if [ $emptyuser -eq 0 ] && [ $unix_socket_auth -ne 1 ] && [ -z "$host" ] && [ "$ while true ; do echo $echo_n "Enable unix_socket authentication? [Y/n] $echo_c" - read reply + read reply || interrupt validate_reply $reply && break done @@ -516,7 +547,7 @@ if [ $emptyuser -eq 0 ] && [ $unix_socket_auth -ne 1 ] && [ -z "$host" ] && [ "$ if [ $? -eq 0 ]; then echo "Enabled successfully!" else - echo "Failed!" + echo "Failed alter user!" clean_and_exit fi fi @@ -538,7 +569,7 @@ while true ; do echo $echo_n "Set the user: $user password? [Y/n] $echo_c" defsetpass=N fi - read reply + read reply || interrupt validate_reply $reply $defsetpass && break done @@ -567,7 +598,7 @@ echo while true ; do echo $echo_n "Remove anonymous users? [Y/n] $echo_c" - read reply + read reply || interrupt validate_reply $reply && break done if [ "$reply" = "n" ]; then @@ -588,15 +619,24 @@ echo "before moving into a production environment." echo while true ; do - echo $echo_n "Remove test database and access to it? [Y/n] $echo_c" - read reply - validate_reply $reply && break + test_db_exists=0 + check_test_database + if [ $? -eq 1 ]; then + test_db_exists=1 + echo $echo_n "Remove test database and access to it? [Y/n] $echo_c" + read reply || interrupt + validate_reply $reply && break + fi + printf " ... Success!\nTest database doesn't exist!" + break done if [ "$reply" = "n" ]; then echo " ... skipping." else - remove_test_database + if [ $test_db_exists -eq 1 ]; then + remove_test_database + fi fi echo @@ -610,7 +650,7 @@ echo "ensures that someone cannot guess at the root password from the network." echo while true ; do echo $echo_n "Disallow root login remotely? [Y/n] $echo_c" - read reply + read reply || interrupt validate_reply $reply && break done if [ "$reply" = "n" ]; then |