4
# Copyright (C) 2002 MySQL AB and Jeremy Cole
6
# This program is free software; you can redistribute it and/or modify
7
# it under the terms of the GNU General Public License as published by
8
# the Free Software Foundation; version 2 of the License.
10
# This program is distributed in the hope that it will be useful,
11
# but WITHOUT ANY WARRANTY; without even the implied warranty of
12
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
# GNU General Public License for more details.
15
# You should have received a copy of the GNU General Public License
16
# along with this program; if not, write to the Free Software
17
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22
my $config = ".my.cnf.$$";
23
my $command = ".mysql.$$";
32
if ($^O eq 'MSWin32') {
40
if ($^O eq 'MSWin32') {
49
-f $file or die "ERROR: file is missing \"$file\": $!";
50
open(FILE, ">$file") or die "ERROR: can't write to file \"$file\": $!";
51
foreach my $line ( @_ ) {
52
print FILE $line, "\n"; # Add EOL char
58
foreach my $file ( $config, $command ) {
59
next if -f $file; # Already exists
61
sysopen(FILE, $file, O_CREAT, 0600)
62
or die "ERROR: can't create $file: $!";
69
write_file($command, $query);
70
system("mysql --defaults-file=$config < $command");
78
"# mysql_secure_installation config file",
81
"password=$rootpass");
84
sub get_root_password {
86
while ( $status == 1 ) {
88
print "Enter current password for root (enter for none): ";
89
my $password = <STDIN>;
96
$rootpass = $password;
97
make_config($rootpass);
101
print "OK, successfully used password, moving on...\n\n";
104
sub set_root_password {
106
print "New password: ";
107
my $password1 = <STDIN>;
108
print "\nRe-enter new password: ";
109
my $password2 = <STDIN>;
113
if ( $password1 eq $password2 ) {
114
print "Sorry, passwords do not match.\n\n";
119
print "Sorry, you can't use an empty password here.\n\n";
123
do_query("UPDATE mysql.user SET Password=PASSWORD('$password1') WHERE User='root';");
125
print "Password updated successfully!\n";
126
print "Reloading privilege tables..\n";
127
if ( !reload_privilege_tables() ) {
131
$rootpass = $password1;
132
make_config($rootpass);
134
print "Password update failed!\n";
141
sub remove_anonymous_users {
142
do_query("DELETE FROM mysql.user WHERE User='';");
144
print " ... Success!\n";
146
print " ... Failed!\n";
153
sub remove_remote_root {
154
do_query("DELETE FROM mysql.user WHERE User='root' AND Host!='localhost';");
156
print " ... Success!\n";
158
print " ... Failed!\n";
162
sub remove_test_database {
163
print " - Dropping test database...\n";
164
do_query("DROP DATABASE test;");
166
print " ... Success!\n";
168
print " ... Failed! Not critical, keep moving...\n";
171
print " - Removing privileges on test database...\n";
172
do_query("DELETE FROM mysql.db WHERE Db='test' OR Db='test\\_%'");
174
print " ... Success!\n";
176
print " ... Failed! Not critical, keep moving...\n";
182
sub reload_privilege_tables {
183
do_query("FLUSH PRIVILEGES;");
185
print " ... Success!\n";
188
print " ... Failed!\n";
194
print "\nAborting!\n\n";
201
print "Cleaning up...\n";
202
unlink($config,$command);
206
# The actual script starts here
214
NOTE: RUNNING ALL PARTS OF THIS SCRIPT IS RECOMMENDED FOR ALL MySQL
215
SERVERS IN PRODUCTION USE! PLEASE READ EACH STEP CAREFULLY!
217
In order to log into MySQL to secure it, we'll need the current
218
password for the root user. If you've just installed MySQL, and
219
you haven't set the root password yet, the password will be blank,
220
so you should just press enter here.
228
# Set the root password
231
print "Setting the root password ensures that nobody can log into the MySQL\n";
232
print "root user without the proper authorisation.\n\n";
234
if ( $hadpass == 0 ) {
235
print "Set root password? [Y/n] ";
237
print "You already have a root password set, so you can safely answer 'n'.\n\n";
238
print "Change the root password? [Y/n] ";
242
if ( $reply =~ /n/i ) {
243
print " ... skipping.\n";
246
while ( $status == 1 ) {
255
# Remove anonymous users
259
By default, a MySQL installation has an anonymous user, allowing anyone
260
to log into MySQL without having to have a user account created for
261
them. This is intended only for testing, and to make the installation
262
go a bit smoother. You should remove them before moving into a
263
production environment.
267
print "Remove anonymous users? [Y/n] ";
269
if ( $reply =~ /n/i ) {
270
print " ... skipping.\n";
272
remove_anonymous_users();
278
# Disallow remote root login
282
Normally, root should only be allowed to connect from 'localhost'. This
283
ensures that someone cannot guess at the root password from the network.
287
print "Disallow root login remotely? [Y/n] ";
289
if ( $reply =~ /n/i ) {
290
print " ... skipping.\n";
292
remove_remote_root();
298
# Remove test database
302
By default, MySQL comes with a database named 'test' that anyone can
303
access. This is also intended only for testing, and should be removed
304
before moving into a production environment.
308
print "Remove test database and access to it? [Y/n] ";
310
if ( $reply =~ /n/i ) {
311
print " ... skipping.\n";
313
remove_test_database();
319
# Reload privilege tables
323
Reloading the privilege tables will ensure that all changes made so far
324
will take effect immediately.
328
print "Reload privilege tables now? [Y/n] ";
330
if ( $reply =~ /n/i ) {
331
print " ... skipping.\n";
333
reload_privilege_tables();
343
All done! If you've completed all of the above steps, your MySQL
344
installation should now be secure.
346
Thanks for using MySQL!