その mysql_secure_installation 本当に必要ですか？

## この記事を書いた背景

MySQL 8.0 や MariaDB 10.3 の初期状態を見て、`mysql_secure_installation`を実行せずに rootユーザーのパスワード設定をするだけで良いんじゃないかという疑問が浮かびました。

しかし、`mysql_secure_installation`について検索してみても使い方の記事ばかりで疑問を解消してくれる記事は見当たらなかった為、自分で確認してみようと思った次第です。

## 目的

`mysql_secure_installtaion`の実行は本当に必要なのか？を確認する。
また、不要になっているのであればいつから不要になったのかも確認しておく。

## 結論

先に結論を書くと、
**MySQL 5.6までは必要、5.7以降は不要** ではないかと思います。
但し冒頭で書いている通り「rootユーザーのパスワード設定」は行う必要があります。

※公式の情報ではない為、鵜呑みにしないで下さい


以降はこの結論に至るまでの過程を書いていきます。


## mysql_secure_installtaion について

`mysql_secure_installtaion`では

・rootユーザーのパスワード設定
・匿名ユーザーの削除
・外部（ローカルホスト以外）からアクセス可能なrootユーザーの削除
・testデータベースの削除
・「test_」から始まるデータベースへの接続権限の削除
・特権テーブルのリロード（更新内容の反映）

以上の6つの処理を実行しているという認識です。
※実行時のメッセージと [公式リファレンス](https://dev.mysql.com/doc/refman/8.0/en/mysql-secure-installation.html) から判断

上記の処理が本当に必要なのか、という点を確認していきます。


## 確認方法

まず [MySQL 5.6 の公式リファレンス](https://dev.mysql.com/doc/refman/5.6/en/default-privileges.html) をチェックした所、MySQL 5.6 では匿名ユーザーや testデータベースの扱い等に触れており、`mysql_secure_installtaion`を使う必要がありそうでした。

しかし、[5.7 の公式リファレンス](https://dev.mysql.com/doc/refman/5.7/en/default-privileges.html ) や [8.0 の公式リファレンス](https://dev.mysql.com/doc/refman/8.0/en/default-privileges.html) では`mysql_secure_installation`の記述は出てきていますが、
5.6 の [Securing the Initial MySQL Accounts](https://dev.mysql.com/doc/refman/5.6/en/default-privileges.html ) に出てきたような記述は見当たりませんでした。

とりあえず、MySQL 5.6 から順番にインストールしてみるのが確実そうです。


## 確認内容

`mysql_secure_installtaion`の実行内容を踏まえて、

① 匿名ユーザーの存在
② 外部（ローカルホスト以外）からアクセス可能なrootユーザーの存在
③ testデータベースの存在
④ test_から始まるデータベースへの接続権限をデフォルトで持っているかどうか

以上の4点を確認します。

rootユーザーのパスワード設定が必要なのは検証前から分かっていた為、ここでは除外します。
また、特権テーブルのリロードは更新内容を反映することが目的である為、これも除外します。


## 検証環境

* OS: Ubuntu Server 20.04 LTS
  * 検証環境は VirtualBox + Vagrant にて作成
* Host name: vagrant

```sh
$ hostname
vagrant
```

## 確認手順

前述の①～④を確認する際に使用したコマンドを説明します。

```sh
> select user, host from mysql.user;
```
ユーザー情報の一覧を取得します。
「① 匿名ユーザーの存在確認」、「② 外部からアクセス可能なrootユーザーの存在確認」に使用しました。

```sh
> show databases;
```
データベースの一覧を取得します。
「③ testデータベースの存在確認」に使用しました。

```sh
> select Host, Db, User from mysql.db;
```
データベースに対するアクセス許可の一覧を取得します。
「④ テストDBアクセス権限確認」に使用しました。


### MySQL 5.6

インストールは以下の記事を参考にしました。
※参考記事　https://qiita.com/ledsun/items/b1c7fdf756593c87f67a

#### rootユーザーでログイン

ついでに、5.6 がインストールされていることを確認

```sh
$ sudo mysql
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 1
Server version: 5.6.14 MySQL Community Server (GPL)

Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
```

#### 確認コマンド実行

```sh
> select user, host from mysql.user;
+------+-----------+
| user | host      |
+------+-----------+
| root | 127.0.0.1 |
| root | ::1       |
|      | localhost |
| root | localhost |
|      | vagrant   |
| root | vagrant   |
+------+-----------+
6 rows in set (0.00 sec)
```

① 匿名ユーザーの存在確認 について
→　匿名ユーザーあり

② 外部からアクセス可能なrootユーザーの存在確認 について
→　「127.0.0.1」、「::1」、「localhost」は自身を指すので問題無し
→　「vagrant」（ホスト名）についてはDNSの設定次第で外部からも接続出来てしまう可能性あり？
　　※知識不足ですみません。御存知の方、御教示頂けないでしょうか。


```sh
> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
| test               |
+--------------------+
4 rows in set (0.00 sec)
```

③ testデータベースの存在確認 について
→　testデータベースあり


```sh
> select Host, Db, User from mysql.db;
+------+---------+------+
| Host | Db      | User |
+------+---------+------+
| %    | test    |      |
| %    | test\_% |      |
+------+---------+------+
2 rows in set (0.01 sec)
```

④ testデータベースアクセス権限確認 について
→　全てのユーザー、ホストから「test」テーブルと[test_」から始まるテーブルに対してアクセス出来る権限があることを確認


#### 結論

MySQL 5.6 では`mysql_secure_installation`は必要


#### 備考

`mysql_secure_installation`の実行によりどう変化するのかを確認

```sh
> select user, host from mysql.user;
+------+-----------+
| user | host      |
+------+-----------+
| root | 127.0.0.1 |
| root | ::1       |
| root | localhost |
+------+-----------+
3 rows in set (0.02 sec)
```

① 匿名ユーザーの存在確認 について
→　匿名ユーザーが消えている

② 外部からアクセス可能なrootユーザーの存在確認 について
→　ホスト名指定が消えている

```sh
> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
+--------------------+
3 rows in set (0.02 sec)
```

③ testデータベースの存在確認 について
→　testテーブルが消えている

```sh
> select Host, Db, User from mysql.db;
Empty set (0.00 sec)
```

④ testデータベースアクセス権限確認 について
→　「test」テーブルと[test_」から始まるテーブルに対してのアクセス権が消えている

### MySQL 5.7


#### rootユーザーでログイン

ついでに、5.7 がインストールされていることを確認

```sh
$ sudo mysql
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 2
Server version: 5.7.33 MySQL Community Server (GPL)

Copyright (c) 2000, 2021, Oracle and/or its affiliates.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
```

#### 確認コマンド実行

```sh
> select user, host from mysql.user;
+---------------+-----------+
| user          | host      |
+---------------+-----------+
| mysql.session | localhost |
| mysql.sys     | localhost |
| root          | localhost |
+---------------+-----------+
3 rows in set (0.00 sec)
```

① 匿名ユーザーの存在確認 について
→　匿名ユーザーなし


② 外部からアクセス可能なrootユーザーの存在確認 について
→　localhost 以外の host指定なし


```sh
> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
| sys                |
+--------------------+
4 rows in set (0.00 sec)
```

③ testデータベースの存在確認 について
→　testデータベースなし


```sh
> select Host, Db, User from mysql.db;
+-----------+--------------------+---------------+
| Host      | Db                 | User          |
+-----------+--------------------+---------------+
| localhost | performance_schema | mysql.session |
| localhost | sys                | mysql.sys     |
+-----------+--------------------+---------------+
2 rows in set (0.00 sec)
```

④ testデータベースアクセス権限確認 について
→　「test」テーブルと「test_」から始まるテーブルに対してアクセスする為の権限は存在しない

#### 結論

MySQL 5.7 の時点で、`mysql_secure_installation`は不要になっている

#### 備考

念の為に、MySQL 5.7 でも`mysql_secure_installation`を実行してみる


```sh
> select user, host from mysql.user;
+---------------+-----------+
| user          | host      |
+---------------+-----------+
| mysql.session | localhost |
| mysql.sys     | localhost |
| root          | localhost |
+---------------+-----------+
3 rows in set (0.00 sec)
```

① 匿名ユーザーの存在確認 について
→　実行前と変化なし

② 外部からアクセス可能なrootユーザーの存在確認 について
→　実行前と変化なし

```sh
> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
| sys                |
+--------------------+
4 rows in set (0.01 sec)
```

③ testデータベースの存在確認 について
→　実行前と変化なし

```sh
> select Host, Db, User from mysql.db;
+-----------+--------------------+---------------+
| Host      | Db                 | User          |
+-----------+--------------------+---------------+
| localhost | performance_schema | mysql.session |
| localhost | sys                | mysql.sys     |
+-----------+--------------------+---------------+
2 rows in set (0.01 sec)
```

④ testデータベースアクセス権限確認 について
→　実行前と変化なし

### MySQL 8.0

MySQL 5.7 の時点で不要になっていると判断していますが、一応 MySQL 8.0 でも確認しておきます。

#### rootユーザーでログイン

ついでに MySQL 8.0 がインストールされていることを確認

```sh
$ sudo mysql
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 8
Server version: 8.0.23-0ubuntu0.20.04.1 (Ubuntu)

Copyright (c) 2000, 2021, Oracle and/or its affiliates.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
```

#### 確認コマンド実行

```sh
> select user, host from mysql.user;
+------------------+-----------+
| user             | host      |
+------------------+-----------+
| debian-sys-maint | localhost |
| mysql.infoschema | localhost |
| mysql.session    | localhost |
| mysql.sys        | localhost |
| root             | localhost |
+------------------+-----------+
5 rows in set (0.00 sec)
```

① 匿名ユーザーの存在確認 について
→　MySQL 5.7 と同様、匿名ユーザーなし

② 外部からアクセス可能なrootユーザーの存在確認 について
→　MySQL 5.7 と同様、localhost 以外の host指定なし

```sh
> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
| sys                |
+--------------------+
4 rows in set (0.00 sec)
```

③ testデータベースの存在確認 について
→　MySQL 5.7 と同様、testデータベースなし

```sh
> select Host, Db, User from mysql.db;
+-----------+--------------------+---------------+
| Host      | Db                | User           |
+-----------+--------------------+---------------+
| localhost | performance_schema | mysql.session |
| localhost | sys                | mysql.sys     |
+-----------+--------------------+---------------+
2 rows in set (0.00 sec)
```

④ testデータベースアクセス権限確認 について
→　MySQL 5.7 と同様、「test」テーブルと「test_」から始まるテーブルに対してアクセスする為の権限は存在しない

#### 結論

MySQL 8.0 でも MySQL 5.7 と同様に、`mysql_secure_installation`は不要

※`mysql_secure_installation`の実行結果は省略します

### MariaDB 10.3

[MariaDB の公式リファレンスにも mysql_secure_installation の記述がある](https://mariadb.com/kb/en/mysql_secure_installation/) ので、 MariaDB 10.3 でも確認


#### rootユーザーでログイン

ついでに MariaDB 10.3 がインストールされていることを確認

```sh
$ sudo mysql
Welcome to the MariaDB monitor.  Commands end with ; or \g.
Your MariaDB connection id is 38
Server version: 10.3.25-MariaDB-0ubuntu0.20.04.1 Ubuntu 20.04

Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
```

#### 確認コマンド実行

```sh
> select user, host from mysql.user;
+------+-----------+
| user | host      |
+------+-----------+
| root | localhost |
+------+-----------+
1 row in set (0.000 sec)
```

① 匿名ユーザーの存在確認 について
→　MySQL 5.7 と同様、匿名ユーザーなし

② 外部からアクセス可能なrootユーザーの存在確認 について
→　MySQL 5.7 と同様、localhost 以外の host指定なし

```sh
> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
+--------------------+
3 rows in set (0.000 sec)
```

③ testデータベースの存在確認 について
→　MySQL 5.7 と同様、testデータベースなし

```sh
> select Host, Db, User from mysql.db;
Empty set (0.000 sec)
```

④ testデータベースアクセス権限確認 について
→　MySQL 5.7 と同様、「test」テーブルと「test_」から始まるテーブルに対してアクセスする為の権限は存在しない

#### 結論

MariaDB 10.3 でも MySQL 5.7 と同様に、`mysql_secure_installation`は不要

## 最後に

MySQL 5.7 以降では不要と結論を出していますが、公式リファレンスには`mysql_secure_installation`の記述が残っている点が気になっています。
また、公式情報を基にした記事ではないので鵜呑みにしないで下さい。

本記事について指摘や補足等あればコメントをお願いします。