この疑問は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 のみ)設計が本番の基本
でも安心してください。プロのエンジニアはコマンドを暗記していません。
「現場で使える型」を効率よく使いこなしているだけです。
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
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 'パスワード';
mysql> CREATE USER 'webapp'@'localhost' IDENTIFIED BY 'Passw0rd!secure'; Query OK, 0 rows affected (0.01 sec)
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)
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)
接続中のユーザー自身の権限を確認するには、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)
ユーザーを完全に削除する場合は DROP USER を使います。
mysql> DROP USER 'webapp'@'localhost'; Query OK, 0 rows affected (0.01 sec)
「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';
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のユーザー管理に必要なコマンドをまとめます。| やりたいこと | コマンド |
|---|---|
| ユーザーを作成する | 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; |
1つは接続元ホストの指定誤り('localhost' と '%' の混同)。もう1つは権限の対象データベース名の不一致です。SHOW GRANTSで付与内容を必ず確認する習慣が、トラブル対応の時間を大幅に削減します。
本番環境ではアプリに必要な権限(SELECT/INSERT/UPDATE/DELETE)だけを与え、CREATE/DROP/ALTER は管理者専用ユーザーに分離する設計を徹底してください。
MySQLのユーザー管理も「Linuxサーバー運用の型」の一部です
ユーザー権限の設計やバックアップ体制の整備は、Linuxサーバー運用の基礎知識と表裏一体です。CREATE USERやGRANTの手順を覚えるだけでなく、セキュリティを意識した設計思想を身につけることで、本番環境を安全に管理できるようになります。
現場で通用する安全なLinuxサーバー構築の「型」を体系的に身につけたい方へ、『Linuxサーバー構築入門マニュアル(図解60P)』を完全無料でプレゼントしています。
「独学の時間がもったいない」「プロから直接、現場の技術を最短で学びたい」という本気の方には、2日で実務レベルのスキルが身につく【初心者向けハンズオンセミナー】も開催しています。
3,100名以上が実践した「型」を無料で公開中
プロのエンジニアはコマンドを暗記していません。
「現場で使える型」を効率よく使いこなしているだけです。
その「型」を図解60Pにまとめた入門マニュアルを、完全無料でプレゼントしています。
姓・名・メールの3つだけ/30秒/解除は3秒 / 詳細はこちら

無料メルマガで学習を続ける
Linuxの実践スキルをメールで毎週お届け。
登録は30秒、解除もいつでも可。
登録無料・いつでも解除できます