MySQLのユーザー作成とGRANT権限付与の実務手順|SHOW GRANTSで確認・REVOKEで剥奪まで

宮崎智広 この記事の監修:宮崎智広(Linux実務・教育歴20年以上・受講者3,100名超)
HOMELinux技術 リナックスマスター.JP(Linuxマスター.JP)Linuxtipsデーターベース管理 > MySQLのユーザー作成とGRANT権限付与の実務手順|SHOW GRANTSで確認・REVOKEで剥奪まで
「MySQLをインストールしたがアプリ用のユーザーをどう作ればいい?」「rootで直接接続しているが、これはまずいのか?」
この疑問はLinuxサーバーにMySQLを自前で導入した直後に必ずぶつかります。

rootで直接アプリを接続するのはセキュリティ上の大きなリスクです。アプリのSQL脆弱性がそのままDB全体の破壊につながる可能性があります。適切なユーザーを作成してデータベース単位で権限を絞る設計が現場の基本です。

この記事では、MySQLのユーザー作成(CREATE USER)・権限付与(GRANT)・確認(SHOW GRANTS)・剥奪(REVOKE)の一連の手順を、RHEL 9.4 / Ubuntu 24.04 LTSで動作確認した実機の出力例を交えて解説します。

この記事のポイント

・ CREATE USER ~ GRANT ~ FLUSH PRIVILEGES 不要(MySQL 8.0)の正しい流れ
・ '%' と 'localhost' の違いを誤ると接続できない現象が起きる
・ SHOW GRANTS で付与済み権限を即確認、REVOKE で即剥奪できる
・ 最小権限(SELECT/INSERT/UPDATE/DELETE のみ)設計が本番の基本


「このままじゃマズい」と感じていませんか?
参考書を開く気力もない、同年代に取り残される不安——
でも安心してください。プロのエンジニアはコマンドを暗記していません。
「現場で使える型」を効率よく使いこなしているだけです。
姓・名・メールの3つだけ/30秒/解除は3秒 / 詳細はこちら

MySQLのユーザー管理で現場が詰まる場面

MySQLのセットアップ直後によくある問題が「rootを共用している」状態です。
Webアプリ・バッチ・管理ツールがすべてrootで接続していると、アプリのSQL脆弱性がそのままDB全体の破壊につながります。

現場でよく見かけるのが次の3パターンです。

rootをそのまま使い続けている(パスワードが平文でアプリ設定ファイルに書かれている)
ユーザーを作ったが接続できない(ホスト指定の誤りが原因)
「Access denied」が出るが原因が分からない(付与した権限とデータベース名が食い違っている)

これらはすべて、CREATE USER → GRANT の手順と「接続元ホスト」の概念を理解することで防げます。順に見ていきましょう。

CREATE USERでユーザーを作成する

1. rootでMySQLにログインする

ユーザー作成にはMySQLの管理者権限が必要です。まずrootでログインします。

# RHEL 9 / CentOS Stream 9 の場合 $ sudo mysql -u root -p # Ubuntu 24.04 の場合(初期インストール後は auth_socket 認証のため sudo で入る) $ sudo mysql

ログイン後はMySQLのプロンプト(mysql>)になります。

Welcome to the MySQL monitor. Commands end with ; or \g. Your MySQL connection id is 10 Server version: 8.0.36 MySQL Community Server - GPL mysql>

2. CREATE USERの構文と実行例

ユーザー作成の基本構文は次のとおりです。

CREATE USER 'ユーザー名'@'接続元ホスト' IDENTIFIED BY 'パスワード';

実際にWebアプリ用のユーザー「webapp」をローカルからのみ接続可能な形で作成する例です。

mysql> CREATE USER 'webapp'@'localhost' IDENTIFIED BY 'Passw0rd!secure'; Query OK, 0 rows affected (0.01 sec)

「Query OK」が返れば作成成功です。ユーザーが存在するか確認するには、mysql.userテーブルを参照します。

mysql> SELECT User, Host FROM mysql.user WHERE User = 'webapp'; +--------+-----------+ | User | Host | +--------+-----------+ | webapp | localhost | +--------+-----------+ 1 row in set (0.00 sec)

3. 接続元ホストの指定('%' と 'localhost' の違い)

MySQLのユーザーは「ユーザー名+接続元ホスト」のセットで識別されます。この仕組みを誤解すると「ユーザーを作ったのに接続できない」という問題が発生します。

'localhost':同一サーバー上のUnixソケット(またはTCP 127.0.0.1)からの接続のみ許可
'127.0.0.1':TCPでの127.0.0.1からの接続のみ許可(ソケット不可)
'%':全ホストからのTCP接続を許可(ファイアウォールで別途制御が前提)
'192.168.10.%':192.168.10.0/24 のネットワークからの接続を許可

アプリサーバーとDBサーバーが別マシンの場合は 'アプリサーバーのIP' か 'アプリサーバーのFQDN' を指定するのが基本です。'%' を使う場合はファイアウォールで3306番ポートへのアクセスを必ず制限してください。

GRANTでデータベースへの権限を付与する

ユーザーを作っただけでは、どのデータベースにもアクセスできません。GRANT文で権限を付与します。

1. GRANT構文の基本形

GRANT 権限リスト ON データベース名.テーブル名 TO 'ユーザー名'@'接続元ホスト';

データベース名とテーブル名には * (ワイルドカード)が使えます。
データベース名.*:そのDB内の全テーブルを対象
*.*:全DBの全テーブルを対象(管理者権限に相当するため通常は使わない)

2. データベース単位で権限を付与する実行例

先ほど作成した「webapp」ユーザーに、「myapp_db」データベースへのアクセス権を与えます。

mysql> GRANT SELECT, INSERT, UPDATE, DELETE ON myapp_db.* TO 'webapp'@'localhost'; Query OK, 0 rows affected (0.00 sec)

これで「webapp」はmyapp_dbに対してSELECT・INSERT・UPDATE・DELETEを実行できるようになります。

3. 権限の種類と最小権限設計

GRANTで指定できる主な権限は次のとおりです。

SELECT:データの読み取り
INSERT:行の挿入
UPDATE:行の更新
DELETE:行の削除
CREATE:テーブル・DBの作成
DROP:テーブル・DBの削除
INDEX:インデックスの作成・削除
ALTER:テーブル定義の変更
REFERENCES:外部キー制約の設定
ALL PRIVILEGES:全権限(*.*の場合はGRANT OPTIONを除く全権限)

本番環境ではアプリが実際に必要とする権限だけを付与するのが原則です。Webアプリであれば SELECT/INSERT/UPDATE/DELETE の4つが基本になります。バックアップ専用ユーザーであれば SELECT と LOCK TABLES だけで十分です。

スキーマ変更(テーブルの作成・削除・変更)はデプロイ手順に組み込み、専用の管理用ユーザー(またはroot)で実行する設計が安全です。

4. MySQL 8.0でFLUSH PRIVILEGESは不要

MySQL 5.x の時代はGRANT後に FLUSH PRIVILEGES を実行する慣習がありましたが、MySQL 8.0 では GRANT 文が直接権限テーブルを更新するため、FLUSH PRIVILEGES は不要です。

ただし、mysql.userテーブルを直接INSERT/UPDATEした場合(推奨しない操作)は従来どおり FLUSH PRIVILEGES が必要です。通常の GRANT/CREATE USER を使う限りは実行しなくて構いません。

SHOW GRANTSで権限を確認する

付与した権限を確認するにはSHOW GRANTSを使います。

mysql> SHOW GRANTS FOR 'webapp'@'localhost'; +-----------------------------------------------------------------------------------+ | Grants for webapp@localhost | +-----------------------------------------------------------------------------------+ | GRANT USAGE ON *.* TO `webapp`@`localhost` | | GRANT SELECT, INSERT, UPDATE, DELETE ON `myapp_db`.* TO `webapp`@`localhost` | +-----------------------------------------------------------------------------------+ 2 rows in set (0.00 sec)

1行目の「GRANT USAGE ON *.*」はユーザーが存在することを示す最低限の定義です。実際の権限は2行目に表示されています。

接続中のユーザー自身の権限を確認するには、SHOW GRANTS; とユーザー指定なしで実行できます。

# webapp ユーザーで接続中の場合 mysql> SHOW GRANTS; +-----------------------------------------------------------------------------------+ | Grants for webapp@localhost | +-----------------------------------------------------------------------------------+ | GRANT USAGE ON *.* TO `webapp`@`localhost` | | GRANT SELECT, INSERT, UPDATE, DELETE ON `myapp_db`.* TO `webapp`@`localhost` | +-----------------------------------------------------------------------------------+ 2 rows in set (0.00 sec)

REVOKEで権限を剥奪する・DROP USERで削除する

付与した権限を取り消すにはREVOKEを使います。構文はGRANTに対応しています。

# DELETE権限だけを剥奪する例 mysql> REVOKE DELETE ON myapp_db.* FROM 'webapp'@'localhost'; Query OK, 0 rows affected (0.01 sec) # 確認 mysql> SHOW GRANTS FOR 'webapp'@'localhost'; +-----------------------------------------------------------------------------------+ | Grants for webapp@localhost | +-----------------------------------------------------------------------------------+ | GRANT USAGE ON *.* TO `webapp`@`localhost` | | GRANT SELECT, INSERT, UPDATE ON `myapp_db`.* TO `webapp`@`localhost` | +-----------------------------------------------------------------------------------+ 2 rows in set (0.00 sec)

DELETE が除かれているのが確認できます。

ユーザーを完全に削除する場合は DROP USER を使います。

mysql> DROP USER 'webapp'@'localhost'; Query OK, 0 rows affected (0.01 sec)

DROP USER はそのユーザーに紐付いたGRANT情報もまとめて削除します。REVOKEしてからDROP USERする必要はありません。

「Access denied for user」が出た時の調査手順

GRANTを実行したのに接続でき場合や「Access denied for user 'webapp'@'localhost'」エラーが出る場合の調査手順です。

1. ユーザーと接続元ホストの組み合わせを確認する

まずrootでログインし、対象ユーザーがmysql.userに存在するかを確認します。

mysql> SELECT User, Host, plugin FROM mysql.user WHERE User = 'webapp'; +--------+-----------+-----------------------+ | User | Host | plugin | +--------+-----------+-----------------------+ | webapp | localhost | caching_sha2_password | +--------+-----------+-----------------------+ 1 row in set (0.00 sec)

2. 接続元ホストの食い違いを確認する

エラーメッセージに表示されるホスト部分に注目します。

'webapp'@'localhost' でエラー → ユーザーが 'webapp'@'127.0.0.1' で作られていないか確認
'webapp'@'192.168.10.5' でエラー → ユーザーが 'webapp'@'localhost' で作られていてTCP接続している可能性

SHOW GRANTSでアクセス可能なホストを確認し、接続時のホスト指定(-h オプション)と一致しているかを照合してください。

3. 対象データベースへの権限があるかを確認する

mysql> SHOW GRANTS FOR 'webapp'@'localhost';

接続自体はできてもSQLを発行した時点でエラーになる場合は、権限の対象データベース名(myapp_db)とアクセスしているデータベース名が一致しているかを確認します。

4. パスワード認証方式の問題(MySQL 8.0 + 古いクライアント)

MySQL 8.0 では認証プラグインのデフォルトが caching_sha2_password に変わっています。古いMySQLクライアントや一部のアプリドライバーが接続できない場合は、ユーザー作成時に認証方式を指定する方法があります。

# 旧来の mysql_native_password で作成する(互換性対応) mysql> CREATE USER 'webapp'@'localhost' IDENTIFIED WITH mysql_native_password BY 'Passw0rd!secure';

ただしmysql_native_passwordは将来的に非推奨になる予定です。可能であればアプリ側のドライバーをアップデートして caching_sha2_password に対応する方が長期的には安全です。

本記事のまとめ

MySQLのユーザー管理に必要なコマンドをまとめます。
やりたいこと コマンド
ユーザーを作成する CREATE USER 'user'@'host' IDENTIFIED BY 'pass';
DB全体に権限を付与する GRANT SELECT,INSERT,UPDATE,DELETE ON db.* TO 'user'@'host';
付与済み権限を確認する SHOW GRANTS FOR 'user'@'host';
特定の権限を剥奪する REVOKE DELETE ON db.* FROM 'user'@'host';
ユーザーを削除する DROP USER 'user'@'host';
全ユーザーとホストを確認する SELECT User, Host FROM mysql.user;
現場でよくある失敗の原因は2つに集約されます。

1つは接続元ホストの指定誤り('localhost' と '%' の混同)。もう1つは権限の対象データベース名の不一致です。SHOW GRANTSで付与内容を必ず確認する習慣が、トラブル対応の時間を大幅に削減します。

本番環境ではアプリに必要な権限(SELECT/INSERT/UPDATE/DELETE)だけを与え、CREATE/DROP/ALTER は管理者専用ユーザーに分離する設計を徹底してください。

MySQLのユーザー管理も「Linuxサーバー運用の型」の一部です

ユーザー権限の設計やバックアップ体制の整備は、Linuxサーバー運用の基礎知識と表裏一体です。CREATE USERやGRANTの手順を覚えるだけでなく、セキュリティを意識した設計思想を身につけることで、本番環境を安全に管理できるようになります。
現場で通用する安全なLinuxサーバー構築の「型」を体系的に身につけたい方へ、『Linuxサーバー構築入門マニュアル(図解60P)』を完全無料でプレゼントしています。

「独学の時間がもったいない」「プロから直接、現場の技術を最短で学びたい」という本気の方には、2日で実務レベルのスキルが身につく【初心者向けハンズオンセミナー】も開催しています。

無料メルマガで学習を続ける

Linuxの実践スキルをメールで毎週お届け。
登録は30秒、解除もいつでも可。

登録無料・いつでも解除できます

暗記不要・1時間後にはサーバーが動く

3,100名以上が実践した「型」を無料で公開中

プロのエンジニアはコマンドを暗記していません。
「現場で使える型」を効率よく使いこなしているだけです。
その「型」を図解60Pにまとめた入門マニュアルを、完全無料でプレゼントしています。

姓・名・メールの3つだけ/30秒/解除は3秒 / 詳細はこちら

Linux無料マニュアル(図解60P) 名前とメールで30秒登録
宮崎 智広

この記事を書いた人

宮崎 智広(みやざき ともひろ)

株式会社イーネットマーキュリー代表。現役のLinuxサーバー管理者として20年以上の実務経験を持ち、これまでに累計3,100名以上のエンジニアを指導してきたLinux教育のプロフェッショナル。「現場で本当に使える技術」を体系的に伝えることをモットーに、実践型のLinuxセミナーの開催や無料マニュアルの配布を通じてLinux人材の育成に取り組んでいる。

趣味は、キャンプにカメラ、トラウト釣り。好きな食べ物は、ラーメンにお酒。休肝日が作れない、酒量を減らせないのが悩み。最近、ドラマ「フライトエンジェル」を観て涙腺が崩壊しました。