Go to the first, previous, next, last section, table of contents.


MySQL 特権はどのように働くか?

MySQL は先進的な非標準のセキュリティ/特権システムを持っています。

特権システムが行えること。

MySQL 特権システムの基本機能は、ホスト上のユーザ名に対しデータ ベースの select, insert, update そして delete 特権を与えることです。

拡張機能は匿名ユーザをもつ能力を含み、LOAD DATA INFILE のような MySQL 固有の機能を使用する許可を与えます。

SQL データベースのユーザ名(MySQL のような)は、UNIX ユーザで行う ことはありません。便利のため、多くの MySQL クライアントは現在の ユーザ名でログインを試みます。しかしこれは --user スイッチで変更 できます。これは、全てのユーザに対しパスワードを持つことなしには、どんな 方法でもデータベースを安全にできないことを意味します。

特権システムがどのように働くか?

MySQL では、ホストとユーザの組合せがユニークとして識別されます。 ユーザのことを考えずに、ホスト+ユーザを考えてください。全てがよりクリア になります。例えば、2つの異なるホストで(異なる特権を持つ) 'Robb' という 名前のユーザを MySQL では衝突無しに持つことができます。

MySQL 特権システムは確実に、各ユーザに許されていることを厳密に 行ないます。システムは、どのユーザどのホスト から どのデータベース に接続したかによって、異なる特権の許可を決定し ます。

あなたの特権はスクリプト mysqlaccess でいつでもテストできます。こ れは Yves Carlier が MySQL 配布に提供しました。 「何故 Access denied エラーになるのか?」節参照 「MySQL をクラッカーに対して安全にする方法」節参照

全ての特権は3つのテーブルに置かれます。user, host そして db です。

user テーブル内で承認される全てのものは、db テーブル内にない全てのデー タベースに有効です。この理由から、個々のデータベースごとに、ユーザ(スー パーユーザは除く)の特権を許可することは賢いことです。

host テーブルは主に ``安全な'' サーバのリストを維持します。TcX では host はローカルネットワーク上の全てのマシンのリストを含んでいます。 これは全ての特権が承認されてます。

接続するユーザの特権は次のアルゴリズムで計算されます:

  1. 最初にテーブルを次でソートします:
    Table Sorted by
    host ワイルドなしのホスト/ワイルドつきのホスト/空のホスト
    db ワイルドなしのホスト/ワイルドつきのホスト/空のホスト
    user ホスト/ユーザ
    まずワイルドカードがないホスト、続いてワイルドカードつきのホスト、そして host = "" のエントリ。各ホスト中では、同じ規則を使用してユーザで ソートします。最後に、db テーブル内で同じ規則を使用して db でソー トします。以下のステップでは、ソートされたテーブルを通して見て、 常に最初に見つけたものを使用します
  2. user テーブルから最初に見つかったものを使用して、接続するユーザの 特権を獲得します。 これを特権のセット Priv と呼びます。
  3. db テーブルから最初に見つかったものを使用して、接続するユーザの特 権を獲得します。
  4. db テーブルに見つかったエントリが host = "" の場合、 Privhost テーブル内の host からの特権を AND します。す なわち両方が "Y" でない全ての特権を削除します。(host <> "" の場合、 Priv は影響されません。この場合、host は、少なくても部分的 に、接続するホストの名前に適合しなければなりません。したがって、この行内 に見つかった特権が接続ホストの情報に適合したとみなされます。)
  5. user テーブルから user についての特権を持つ Priv を OR (追 加)します。すなわち、user 内の "Y" である全ての特権を追加します。
テーブルを変更した場合、変更の効果を得るためには mysqladmin reload をしなけれないけないことを覚えておいてください。 接続するユーザは特権 Priv のセットを得ます。 ソートと適合の例を示しましょう! user テーブルがこれを含んでいると仮定し ます:
+-----------+----------+-
| Host      | User     | ...
+-----------+----------+-
| %         | root     | ...
| %         | jeffrey  | ...
| localhost | root     | ...
| localhost |          | ...
+-----------+----------+-
すると検索順は次になります: そのため、localhost 上で接続を試みる jeffrey は localhost/any 行 に適合します。any/jeffrey 行ではありません。最初に見つかった適合 が使用されます! もしアクセスの問題があった場合は、user テーブルを出力し、手動でソートして、ど のように適合されるかを見てください。 ここで、'localhost', 'server.domain' そして 'whitehouse.gov' のホストか ら接続が可能なユーザ 'custom' を追加する例を示します。彼はパスワード 'stupid' を持つことを望みます。データベース 'bankaccount' は 'localhost' からだけ 使用でき、そして 'customer' データベースは全ての3つのホストから到達でき ます。
shell> mysql mysql.
mysql> insert into user (host,user,password)
       values('localhost','custom',password('stupid'));
mysql> insert into user (host,user,password)
       values('server.domain','custom',password('stupid'));
mysql> insert into user (host,user,password)
       values('whitehouse.gov','custom',password('stupid'));

mysql> insert into db
       (host,db,user,Select_priv,Insert_priv,Update_priv,Delete_priv,
        Create_priv,Drop_priv)
       values
       ('localhost','bankaccount','custom','Y','Y','Y','Y','Y','Y');
mysql> insert into db
       (host,db,user,Select_priv,Insert_priv,Update_priv,Delete_priv,
        Create_priv,Drop_priv)
       values
       ('%','customers','custom','Y','Y','Y','Y','Y','Y');
もちろん、xmysqladmin, mysql_webadmin, mysqladmin そして xmysql を使って も、特権テーブルへの値の挿入/変更/更新ができます。これらのユーティリティは Contrib ディレクトリ内に見つけることができます。

特権テーブル

行の承認テーブルの特権は select, insert, update そして delete です。

テーブルとデータベースの特権は createdrop です。create と drop はテーブルとデータベースの両方に働きます。drop 権限を持つユーザは任意 のテーブルを削除できるため、これはデータベースの drop 権限と同じことです。

他の特権は(LOAD DATA INFILESELECT INTO OUTFILE のため の)ファイルの使用と、管理コマンド shutdown, reload, refresh, process の使用の権利を与えます。

特権システムは3つのテーブルに基づきます。

user テーブル
mysql サーバへの接続が許可される全てのホスト+ユーザの組み合わせ(とオプショ ンのパスワード)を含みます。user テーブルは次の項目を持ちます:
Field Type Key Default
Host char(60) PRI ""
User char(16) PRI ""
Password char(16) - ""
Select_priv enum('N','Y') - N
Insert_priv enum('N','Y') - N
Update_priv enum('N','Y') - N
Delete_priv enum('N','Y') - N
Create_priv enum('N','Y') - N
Drop_priv enum('N','Y') - N
Reload_priv enum('N','Y') - N
Shutdown_priv enum('N','Y') - N
Process_priv enum('N','Y') - N
File_priv enum('N','Y') - N
  • db テーブル ホスト+ユーザが使用を許されるデータベースと、その人が各データベースでテー ブルに行えることを含みます。db テーブルは次の項目を持ちます:
    Field Type Key Default
    Host char(60) PRI ""
    Db char(64) PRI ""
    User char(16) PRI ""
    Select_priv enum('N','Y') - N
    Insert_priv enum('N','Y') - N
    Update_priv enum('N','Y') - N
    Delete_priv enum('N','Y') - N
    Create_priv enum('N','Y') - N
    Drop_priv enum('N','Y') - N
  • host テーブル db テーブル内に空の host エントリが見られるような大きなネットワークでだ けに使用されます。これは、あなたのネットワーク内の全てのホストからユーザ にデータベースを使用させたい場合、db テーブルのホスト名として '' を置く べきであることを意味します。この場合 host テーブルは、あなたのネッ トワーク内の全てのホストのエントリを含むべきです。host テーブルは 次の項目を持ちます:
    Field Type Key Default
    Host char(60) PRI ""
    Db char(64) PRI ""
    Select_priv enum('N','Y') - N
    Insert_priv enum('N','Y') - N
    Update_priv enum('N','Y') - N
    Delete_priv enum('N','Y') - N
    Create_priv enum('N','Y') - N
    Drop_priv enum('N','Y') - N
  • IP C-ネットアクセス上の全てのユーザに与えるために、host テーブル内に 123.444.444.% のようなエントリを使用できます。誰かがホスト 123.444.444.somwehere.com という名前のホストによって、この設定を 馬鹿にする試みの可能性を回避するため、MySQL は数値とドットで始 まる全てのホスト名を許可しません。そのためあなたのホストが 1.2.foo.com のような名前の場合、名前の適合で認められることはあり ません。この場合は IP 番号を使用してください。

    新しいユーザ特権の MySQL への追加

    MySQL データベースに特権を追加するために:

    現在のユーザが mysql db テーブルについての insert 特権と reload 特権を持ってい ると仮定します。サーバ (mysqld) が実行されていないといけません。そうでな い場合は、safe_mysqld --log & で開始します。

    > mysql mysql
      insert into user values ('%','monty',password('something'),'Y','Y','Y','Y','Y','Y','Y','Y','Y','Y') ;
      insert into user (host,user,password) values('localhost','dummy','') ;
      insert into user values ('%','admin','','N','N','N','N','N','N','Y','N','Y','Y') ;
      quit
    > mysqladmin reload
    

    これは3つの新しいユーザを作ります:

    Monty
    完全なスーパーユーザ。しかし、MySQL を使用する時にはパスワード を使用する必要があります。
    admin
    パスワードを必要としませんが、mysqladmin reload, mysqladmin refresh そして mysqladmin processlist の使用だけが許されます。テーブル db を通して個々のデータベース特権が承認されます。
    dummy
    db を通して個々のデータベース特権が承認される必要があります。

    デフォルト特権。

    デフォルトの特権 (`scripts/mysql_install_db'内でセットされる) は root に全てを行なえるようにします。全てのユーザは 'test' という名前また は 'test_' で始まる名前の全てのデータベースで全てを行なうことができます。 通常のユーザは mysqladmin shutdown または mysqladmin processlist は使用できません。他のユーザを追加する方法の例は、スクリプ ト (`scripts/mysql_install_db') を参照してください。

    特権テーブルは mysqladmin reload で mysqld に読み込まれます。

    パーミッション設定の例。

    ありがちな間違いは、パスワードが暗号化されて格納されることを忘れることで す。これは次のように指示されます:

    INSERT INTO user VALUES ('%','jeffrey','bLa81m0','Y','Y','Y','N','N','N','N','N', 'N','N');

    そして(もちろん)認証の変更を有効にするために mysqladmin reload を 行ない、それからサーバに接続を試みます:

    $ ./mysql -h sqlserver -u jeffrey -p bLa81m0 test
    Access denied
    

    代わりにこれを試みて下さい:

    INSERT INTO user VALUES
    ('%','jeffrey',password('bLa81m0'),'Y','Y','Y','N','N','N','N','N','N','N');
    

    前と同じように、認証の変更を有効にするために mysqladmin reload を 行ないます。

    さあ、これでちゃんと働きます。

    何故 Access denied エラーになるのか?

    MySQL をクラッカーに対して安全にする方法

    MySQL システムを安全にするためには、次のことを考えるべきです:

    mysqld への次のオプションはセキュリティに影響します:

    --secure
    get_hostbyname から返される ip がオリジナルのホスト名に戻せるかど うかをチェックします。これは、外の誰かが他のホストを真似てアクセスを得る ことを難しくします。このオプションはいくつかの正しいホスト名チェックも追 加します。これは、時にチェックに長い時間がかかるため、デフォルトではオフ にされています。
    --skip-grant-tables
    特権システムを全く使用しません。これは全員に全てのデータベースへの 完全なアクセス を与えます!
    --skip-name-resolve
    ホスト名を解析しません。特権テーブル中の全てのホスト名は IP 番号か 'localhost' でなければなりません。
    --skip-networking
    ネットワーク (TCP/IP) 経由の接続を許可しません。mysqld への全ての接続は、 Unix ソケットで行われます。MIT-pthreads は Unix ソケットをサポートしない ため、このオプションは MIT-pthreads を使用するシステム上では、うまく働き ません。


    Go to the first, previous, next, last section, table of contents.