MySQLの管理者権限といえば、やはりSUPERを思い浮かべる方が多いのではないかと思います。実際、少し前までの運用では、管理系の操作が必要になったときに
ただ、MySQL 8.
ここで大事なのは、SUPERは単に
本稿では、SUPERに頼る前提から少し離れて、MySQL 8.
SUPER権限
SUPERが長く使われてきたのは、単純に便利だったからだと思います。管理系の操作をいろいろまとめて許可できるので、アカウント設計を細かく考えなくても、とりあえず作業は進みます。
ただ、その便利さの裏側では、本当はそこまで強い権限がいらないユーザーにも、かなり広い権限を渡してしまいやすい、という問題がありました。必要最小限の権限で設計したいと思っても、昔はあまりきれいに分けられなかったわけです。
その点、最近のMySQLでは、管理系の権限がかなり細かく分かれています。これは少し面倒に見える反面、設計としてはむしろやりやすくなっています。たとえば
なので、いま考えるべきなのは、
システム変数
比較的わかりやすいのが、システム変数の変更です。以前は、運用担当者にパラメータ変更をさせたいとなると、かなり雑にSUPERを付けていたケースもあったのではないでしょうか。
現在は、このあたりをSYSTEM_
たとえば、実行時のパラメータ変更を行う運用担当向けには、次のようにロールを切り出せます。
CREATE ROLE role_ops_runtime;
GRANT SYSTEM_VARIABLES_ADMIN, CONNECTION_ADMIN ON *.* TO role_ops_runtime;
CREATE USER 'ops'@'10.%' IDENTIFIED BY 'strong-password';
GRANT role_ops_runtime TO 'ops'@'10.%';
SET DEFAULT ROLE role_ops_runtime TO 'ops'@'10.%';
ここではCONNECTION_
このあたりで大事なのは、SUPERのときのように全部まとめて考えないことです。何をさせたいのかを少し切り分けるだけで、必要な権限の見え方がかなり変わってきます。
接続制御
実際に運用していると、設定変更と接続制御は同じではない、と感じる場面があると思います。たとえばoffline_
この点は、権限の上でも分かれてきています。まず、グローバルなシステム変数を変更するには、基本的にSYSTEM_
つまり、ここでは少なくとも2つの責務があります。1つは
これは少し地味ですが、運用上はかなり大きい変化だと思います。障害対応で一時的に接続制御まで必要な人、日常的な設定調整だけをする人、基盤全体を管理する人は、本来同じ権限でなくてもよいからです。SUPER1つでまとめてしまうと、その違いが見えにくくなります。逆に、SYSTEM_
SYSTEM_USER
SYSTEM_
たとえば、CREATE USERやGRANTができるアカウントがあったとしても、それだけで重要なシステムアカウントまで自由に触れてしまうのは、あまりうれしくありません。複数チームで運用している環境なら、なおさらです。
そこでSYSTEM_
CREATE ROLE role_platform_admin;
GRANT CREATE USER, SYSTEM_USER ON *.* TO role_platform_admin;
CREATE USER 'platform_admin'@'localhost' IDENTIFIED BY 'strong-password';
GRANT role_platform_admin TO 'platform_admin'@'localhost';
SET DEFAULT ROLE role_platform_admin TO 'platform_admin'@'localhost';
こういう分け方をしておくと、
SYSTEM_
DEFINER
権限の見直しが効いてくるのは、定常運用だけではありません。移行や復元のような作業でも、強い権限をどう扱うかは意外と重要です。
わかりやすいのが、DEFINERを持つオブジェクトです。ビュー、ストアドルーチン、トリガー、イベントなどを別環境に持っていくと、DEFINERに指定されたアカウントが復元先に存在しない、といったことが起きます。実際、ここでハマったことがある方も多いのではないでしょうか。
こういう場面で、昔の感覚のままSUPERで通してしまうと、移行用のアカウントが必要以上に強くなりがちです。8.
CREATE ROLE role_definer_migration;
GRANT SET_ANY_DEFINER, ALLOW_NONEXISTENT_DEFINER ON *.* TO role_definer_migration;
CREATE USER 'schema_migrator'@'192.168.%' IDENTIFIED BY 'strong-password';
GRANT CREATE, ALTER, DROP, CREATE ROUTINE, ALTER ROUTINE, EXECUTE ON appdb.* TO 'schema_migrator'@'192.168.%';
GRANT role_definer_migration TO 'schema_migrator'@'192.168.%';
SET DEFAULT ROLE role_definer_migration TO 'schema_migrator'@'192.168.%';
普段はいらないが、特定の作業では必要になる権限は意外とあります。そういうものほど、常設の強い管理権限に混ぜないほうがよさそうです。
PERSIST
もう1つ、見直しておきたいのが、実行時変更と永続化の違いです。SET GLOBALでその場の挙動を変えるのと、SET PERSISTで再起動後にも残るようにするのとでは、運用上の意味がかなり違います。
障害対応や一時的な性能調整で、その場だけ設定を変えたいことはあります。ただ、その変更が今後の再起動後も残ってよいかというと、必ずしもそうではありません。ここを同じ権限で扱うと、少し危うい場面が出てきます。
そこで、実行時変更用と、永続化までできるロールを分ける考え方が出てきます。
CREATE ROLE role_runtime_tuner;
GRANT SYSTEM_VARIABLES_ADMIN ON *.* TO role_runtime_tuner;
CREATE ROLE role_persist_tuner;
GRANT SYSTEM_VARIABLES_ADMIN, PERSIST_RO_VARIABLES_ADMIN ON *.* TO role_persist_tuner;
こうしておくと、その場の調整はできるが、将来にも影響する設定までは変えられない、という役割を作れます。本番運用では、この違いはわりと大きいと思います。
SUPER権限棚卸し
SUPER権限から脱却するために何から始めるのがよいでしょうか。結局のところ、まずはSUPERを持っているアカウントを確認するところからだと思います。
しかもこれは、単なる整理ではなく、将来の削除に備える作業でもあります。公式マニュアルでも、SUPERを持つアカウントを洗い出し、適切な動的権限へ移行するよう案内されています。つまり、いまSUPERを棚卸しすること自体が、そのまま将来対応になります。
大事なのは、
権限の確認にはSHOW GRANTSが便利です。
SHOW GRANTS FOR 'legacy_admin'@'%';
SHOW GRANTS FOR 'ops'@'10.%';
SHOW GRANTS FOR 'schema_migrator'@'192.168.%';
もちろん、いきなり全部置き換えるのは現実的ではないかもしれません。ただ、新しいアカウントではSUPERを使わないようにする、既存のものは用途ごとに少しずつ必要な権限だけを付与する、という進め方ならやりやすいのではないかと思います。
おわりに
SUPERは便利ですし、これまで長く使われてきた理由もよくわかります。ただ、SUPERにはあまりにも多くの権限が集約されてされておりとりあえずの管理者権限としては過剰な場合が多いです。
しかもSUPERはすでに非推奨で、将来のバージョンでは削除予定です。そう考えると、もはや
8.
アップグレードというと、新機能や非互換に目が向きがちです。ただ、そのタイミングは運用の前提を見直す機会でもあります。もしSUPERが惰性で残っているなら、この機会に一度棚卸ししてみるのは悪くないはずです。SUPERのその後を考えることは、そのまま、これからのMySQL運用を整えることにもつながるのではないでしょうか。
MySQLで提供されている権限については以下をご覧ください。